From 797e9df01dfc7a352f80c3ffc8f1f48d0b2d94cf Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 07:30:00 +0100 Subject: [PATCH 001/130] Moved mock model identicators to RimDefines --- ApplicationCode/Application/RiaApplication.cpp | 6 +++--- ApplicationCode/ProjectDataModel/RimDefines.h | 9 +++++++++ ApplicationCode/ProjectDataModel/RimResultCase.cpp | 6 +++--- ApplicationCode/UserInterface/RiuMainWindow.cpp | 6 +++--- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/ApplicationCode/Application/RiaApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp index 15d74e3665..456443e89a 100644 --- a/ApplicationCode/Application/RiaApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -637,7 +637,7 @@ bool RiaApplication::openInputEclipseCaseFromFileNames(const QStringList& fileNa //-------------------------------------------------------------------------------------------------- void RiaApplication::createMockModel() { - openEclipseCase("Result Mock Debug Model Simple", "Result Mock Debug Model Simple"); + openEclipseCase(RimDefines::mockModelBasic(), RimDefines::mockModelBasic()); } //-------------------------------------------------------------------------------------------------- @@ -645,7 +645,7 @@ void RiaApplication::createMockModel() //-------------------------------------------------------------------------------------------------- void RiaApplication::createResultsMockModel() { - openEclipseCase("Result Mock Debug Model With Results", "Result Mock Debug Model With Results"); + openEclipseCase(RimDefines::mockModelBasicWithResults(), RimDefines::mockModelBasicWithResults()); } @@ -654,7 +654,7 @@ void RiaApplication::createResultsMockModel() //-------------------------------------------------------------------------------------------------- void RiaApplication::createLargeResultsMockModel() { - openEclipseCase("Result Mock Debug Model Large With Results", "Result Mock Debug Model Large With Results"); + openEclipseCase(RimDefines::mockModelLargeWithResults(), RimDefines::mockModelLargeWithResults()); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimDefines.h b/ApplicationCode/ProjectDataModel/RimDefines.h index 62e33fa8c3..d39cb86dcb 100644 --- a/ApplicationCode/ProjectDataModel/RimDefines.h +++ b/ApplicationCode/ProjectDataModel/RimDefines.h @@ -40,5 +40,14 @@ class RimDefines }; static QString undefinedResultName() { return "None"; } + + + // Mock model text identifiers + static QString mockModelBasic() { return "Result Mock Debug Model Simple"; } + static QString mockModelBasicWithResults() { return "Result Mock Debug Model With Results"; } + static QString mockModelLargeWithResults() { return "Result Mock Debug Model Large With Results"; } + static QString mockModelBasicInputCase() { return "Input Mock Debug Model Simple"; } + + }; diff --git a/ApplicationCode/ProjectDataModel/RimResultCase.cpp b/ApplicationCode/ProjectDataModel/RimResultCase.cpp index b4098e4408..7118479742 100644 --- a/ApplicationCode/ProjectDataModel/RimResultCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultCase.cpp @@ -192,7 +192,7 @@ cvf::ref RimResultCase::createMockModel(QString modelName) cvf::ref mockFileInterface = new RifReaderMockModel; cvf::ref reservoir = new RigCaseData; - if (modelName == "Result Mock Debug Model Simple") + if (modelName == RimDefines::mockModelBasic()) { // Create the mock file interface and and RigSerervoir and set them up. mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(20, 20, 20)); @@ -214,7 +214,7 @@ cvf::ref RimResultCase::createMockModel(QString modelName) //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); } } - else if (modelName == "Result Mock Debug Model With Results") + else if (modelName == RimDefines::mockModelBasicWithResults()) { mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(-20, -20, -20)); mockFileInterface->setGridPointDimensions(cvf::Vec3st(5, 10, 20)); @@ -227,7 +227,7 @@ cvf::ref RimResultCase::createMockModel(QString modelName) cvf::Vec3d& tmp = reservoir->mainGrid()->nodes()[1]; tmp += cvf::Vec3d(1, 0, 0); } - else if (modelName =="Result Mock Debug Model Large With Results") + else if (modelName == RimDefines::mockModelLargeWithResults()) { double startX = 0; double startY = 0; diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index 8013128714..9cf94b5d4f 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -1435,9 +1435,9 @@ void RiuMainWindow::slotOpenMultipleCases() if (1) { - gridFileNames += "Result Mock Debug Model With Results"; - gridFileNames += "Result Mock Debug Model With Results"; - gridFileNames += "Result Mock Debug Model With Results"; + gridFileNames += RimDefines::mockModelBasicWithResults(); + gridFileNames += RimDefines::mockModelBasicWithResults(); + gridFileNames += RimDefines::mockModelBasicWithResults(); } else { From 314512e4054c41c40f8be18c7668380089e771b6 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 10:30:11 +0100 Subject: [PATCH 002/130] Added serialization of pdm objects using QSettings --- Fwk/AppFwk/cafUserInterface/CMakeLists.txt | 2 + .../cafUserInterface/cafPdmSettings.cpp | 116 ++++++++++++++++++ Fwk/AppFwk/cafUserInterface/cafPdmSettings.h | 55 +++++++++ 3 files changed, 173 insertions(+) create mode 100644 Fwk/AppFwk/cafUserInterface/cafPdmSettings.cpp create mode 100644 Fwk/AppFwk/cafUserInterface/cafPdmSettings.h diff --git a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt index fdf3cde039..61b9318fb9 100644 --- a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt +++ b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt @@ -12,6 +12,7 @@ set( QOBJECT_HEADERS cafUiTreeModelPdm.h cafUiProcess.h + cafPdmSettings.h cafPdmUiLineEditor.h cafPdmUiCheckBoxEditor.h cafPdmUiComboBoxEditor.h @@ -38,6 +39,7 @@ endif() add_library( ${PROJECT_NAME} cafBasicAboutDialog.cpp cafBasicAboutDialog.h + cafPdmSettings.cpp cafPdmUiCheckBoxEditor.cpp cafPdmUiCheckBoxEditor.h cafPdmUiColorEditor.cpp diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmSettings.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmSettings.cpp new file mode 100644 index 0000000000..a8e3a3ba5c --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmSettings.cpp @@ -0,0 +1,116 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmSettings.h" +#include "cafPdmField.h" + +#include + + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Settings::readFieldsFromApplicationStore(caf::PdmObject* object) +{ + // Qt doc : + // + // Constructs a QSettings object for accessing settings of the application and organization + // set previously with a call to QCoreApplication::setOrganizationName(), + // QCoreApplication::setOrganizationDomain(), and QCoreApplication::setApplicationName(). + QSettings settings; + + QString prefix = object->classKeyword(); + if (!prefix.isEmpty()) + { + prefix += "/"; + } + + std::vector fields; + object->fields(fields); + size_t i; + for (i = 0; i < fields.size(); i++) + { + caf::PdmFieldHandle* fieldHandle = fields[i]; + + QString keywordWithPrefix = prefix + fieldHandle->keyword(); + if (settings.contains(keywordWithPrefix)) + { + QVariant val = settings.value(keywordWithPrefix); + fieldHandle->setValueFromUi(val); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Settings::writeFieldsToApplicationStore(caf::PdmObject* object) +{ + assert(object); + + // Qt doc : + // + // Constructs a QSettings object for accessing settings of the application and organization + // set previously with a call to QCoreApplication::setOrganizationName(), + // QCoreApplication::setOrganizationDomain(), and QCoreApplication::setApplicationName(). + QSettings settings; + + QString prefix = object->classKeyword(); + if (!prefix.isEmpty()) + { + prefix += "/"; + } + + std::vector fields; + object->fields(fields); + + size_t i; + for (i = 0; i < fields.size(); i++) + { + caf::PdmFieldHandle* fieldHandle = fields[i]; + + QString keywordWithPrefix = prefix + fieldHandle->keyword(); + settings.setValue(keywordWithPrefix, fieldHandle->uiValue()); + } +} + + +} // namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmSettings.h b/Fwk/AppFwk/cafUserInterface/cafPdmSettings.h new file mode 100644 index 0000000000..2342eacd71 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmSettings.h @@ -0,0 +1,55 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include + +namespace caf +{ + + class PdmObject; + +class Settings +{ +public: + static void readFieldsFromApplicationStore(caf::PdmObject* object); + static void writeFieldsToApplicationStore(caf::PdmObject* object); +}; + + +} // end namespace caf From e43bcd56b96af6bfc2580302b68ecccfe98ae822 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 10:30:58 +0100 Subject: [PATCH 003/130] Added mock model settings --- .../ProjectDataModel/CMakeLists_files.cmake | 2 + .../ProjectDataModel/RimMockModelSettings.cpp | 73 +++++++++++++++++++ .../ProjectDataModel/RimMockModelSettings.h | 52 +++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp create mode 100644 ApplicationCode/ProjectDataModel/RimMockModelSettings.h diff --git a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake index 8dd1c8bebe..f6560de705 100644 --- a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake @@ -44,6 +44,7 @@ ${CEE_CURRENT_LIST_DIR}RimStatisticsCaseEvaluator.h ${CEE_CURRENT_LIST_DIR}RimMimeData.h ${CEE_CURRENT_LIST_DIR}RimCommandObject.h ${CEE_CURRENT_LIST_DIR}RimTools.h +${CEE_CURRENT_LIST_DIR}RimMockModelSettings.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -86,6 +87,7 @@ ${CEE_CURRENT_LIST_DIR}RimStatisticsCaseEvaluator.cpp ${CEE_CURRENT_LIST_DIR}RimMimeData.cpp ${CEE_CURRENT_LIST_DIR}RimCommandObject.cpp ${CEE_CURRENT_LIST_DIR}RimTools.cpp +${CEE_CURRENT_LIST_DIR}RimMockModelSettings.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp b/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp new file mode 100644 index 0000000000..3e032f107a --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimMockModelSettings.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 "RiaStdInclude.h" + + +#include "RimMockModelSettings.h" + + + + +CAF_PDM_SOURCE_INIT(RimMockModelSettings, "MockModelSettings"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMockModelSettings::RimMockModelSettings() +{ + CAF_PDM_InitObject("Mock Model Settings", "", "", ""); + + CAF_PDM_InitField(&cellCountX, "CellCountX", quint64(100), "Cell Count X", "", "", ""); + CAF_PDM_InitField(&cellCountY, "CellCountY", quint64(100), "Cell Count Y", "", "", ""); + CAF_PDM_InitField(&cellCountZ, "CellCountZ", quint64(100), "Cell Count Z", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&totalCellCount, "TotalCellCount", "Total Cell Count", "", "", ""); + totalCellCount.setUiReadOnly(true); + + CAF_PDM_InitField(&resultCount, "ResultCount", quint64(3), "Result Count", "", "", ""); + CAF_PDM_InitField(&timeStepCount, "TimeStepCount", quint64(10), "Time Step Count", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMockModelSettings::~RimMockModelSettings() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMockModelSettings::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + totalCellCount = cellCountX * cellCountY * cellCountZ; + totalCellCount.updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMockModelSettings::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + caf::PdmUiGroup* gridSizeGroup = uiOrdering.addNewGroup("Grid size"); + gridSizeGroup->add(&cellCountX); + gridSizeGroup->add(&cellCountY); + gridSizeGroup->add(&cellCountZ); + gridSizeGroup->add(&totalCellCount); +} diff --git a/ApplicationCode/ProjectDataModel/RimMockModelSettings.h b/ApplicationCode/ProjectDataModel/RimMockModelSettings.h new file mode 100644 index 0000000000..64d1beac66 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimMockModelSettings.h @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPointer.h" + + +//================================================================================================== +/// +/// +//================================================================================================== +class RimMockModelSettings : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + + RimMockModelSettings(); + virtual ~RimMockModelSettings(); + + caf::PdmField cellCountX; + caf::PdmField cellCountY; + caf::PdmField cellCountZ; + + caf::PdmField totalCellCount; + + caf::PdmField resultCount; + caf::PdmField timeStepCount; + + + virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); + + virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ); + +}; From 2315ab9014ae84132f0da76ca5b9f8fbb77040d1 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 10:31:46 +0100 Subject: [PATCH 004/130] Added flag to control adding of well data --- .../ReservoirDataModel/RigReservoirBuilderMock.cpp | 14 +++++++++++++- .../ReservoirDataModel/RigReservoirBuilderMock.h | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp index 1c79a5bc77..7c1f5a203e 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp @@ -34,6 +34,7 @@ RigReservoirBuilderMock::RigReservoirBuilderMock() m_resultCount = 0; m_timeStepCount = 0; m_gridPointDimensions = cvf::Vec3st::ZERO; + m_enableWellData = true; } //-------------------------------------------------------------------------------------------------- @@ -246,7 +247,10 @@ void RigReservoirBuilderMock::populateReservoir(RigCaseData* eclipseCase) eclipseCase->mainGrid()->setGridPointDimensions(m_gridPointDimensions); - addWellData(eclipseCase, eclipseCase->mainGrid()); + if (m_enableWellData) + { + addWellData(eclipseCase, eclipseCase->mainGrid()); + } // Set all cells active RigActiveCellInfo* activeCellInfo = eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); @@ -479,3 +483,11 @@ void RigReservoirBuilderMock::addWellData(RigCaseData* eclipseCase, RigGridBase* eclipseCase->setWellResults(wells); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigReservoirBuilderMock::enableWellData(bool enableWellData) +{ + m_enableWellData = false; +} + diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h index d6c0f0fec4..2fb587d85b 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h @@ -48,6 +48,7 @@ class RigReservoirBuilderMock void setWorldCoordinates(cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate); void setGridPointDimensions(const cvf::Vec3st& gridPointDimensions); void setResultInfo(size_t resultCount, size_t timeStepCount); + void enableWellData(bool enableWellData); size_t resultCount() const { return m_resultCount; } size_t timeStepCount() const { return m_timeStepCount; } @@ -90,6 +91,7 @@ class RigReservoirBuilderMock cvf::Vec3st m_gridPointDimensions; size_t m_resultCount; size_t m_timeStepCount; + bool m_enableWellData; std::vector m_localGridRefinements; }; From 93ba02c7db2777e54d0f8833398ede5240737030 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 10:32:24 +0100 Subject: [PATCH 005/130] Added customized mock model to user interface --- .../Application/RiaApplication.cpp | 11 +++++++- ApplicationCode/Application/RiaApplication.h | 1 + .../FileInterface/RifReaderMockModel.cpp | 8 ++++++ .../FileInterface/RifReaderMockModel.h | 1 + ApplicationCode/ProjectDataModel/RimDefines.h | 1 + .../ProjectDataModel/RimInputCase.cpp | 6 ++--- .../ProjectDataModel/RimResultCase.cpp | 27 +++++++++++++++++++ .../UserInterface/RiuMainWindow.cpp | 15 ++++++++--- ApplicationCode/UserInterface/RiuMainWindow.h | 2 ++ 9 files changed, 64 insertions(+), 8 deletions(-) diff --git a/ApplicationCode/Application/RiaApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp index 456443e89a..78766fbe2d 100644 --- a/ApplicationCode/Application/RiaApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -657,12 +657,21 @@ void RiaApplication::createLargeResultsMockModel() openEclipseCase(RimDefines::mockModelLargeWithResults(), RimDefines::mockModelLargeWithResults()); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaApplication::createMockModelCustomized() +{ + openEclipseCase(RimDefines::mockModelCustomized(), RimDefines::mockModelCustomized()); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiaApplication::createInputMockModel() { - openInputEclipseCaseFromFileNames(QStringList("Input Mock Debug Model Simple")); + openInputEclipseCaseFromFileNames(QStringList(RimDefines::mockModelBasicInputCase())); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Application/RiaApplication.h b/ApplicationCode/Application/RiaApplication.h index 39744c7da1..c6721b2439 100644 --- a/ApplicationCode/Application/RiaApplication.h +++ b/ApplicationCode/Application/RiaApplication.h @@ -80,6 +80,7 @@ class RiaApplication : public QApplication void createMockModel(); void createResultsMockModel(); void createLargeResultsMockModel(); + void createMockModelCustomized(); void createInputMockModel(); QString defaultFileDialogDirectory(const QString& dialogName); diff --git a/ApplicationCode/FileInterface/RifReaderMockModel.cpp b/ApplicationCode/FileInterface/RifReaderMockModel.cpp index f03a79e40f..64507ebc8d 100644 --- a/ApplicationCode/FileInterface/RifReaderMockModel.cpp +++ b/ApplicationCode/FileInterface/RifReaderMockModel.cpp @@ -175,3 +175,11 @@ void RifReaderMockModel::populateReservoir(RigCaseData* eclipseCase) m_reservoirBuilder.populateReservoir(eclipseCase); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderMockModel::enableWellData(bool enableWellData) +{ + m_reservoirBuilder.enableWellData(enableWellData); +} + diff --git a/ApplicationCode/FileInterface/RifReaderMockModel.h b/ApplicationCode/FileInterface/RifReaderMockModel.h index 0237381bbe..3acd5a7c7b 100644 --- a/ApplicationCode/FileInterface/RifReaderMockModel.h +++ b/ApplicationCode/FileInterface/RifReaderMockModel.h @@ -30,6 +30,7 @@ class RifReaderMockModel : public RifReaderInterface void setWorldCoordinates(cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate); void setGridPointDimensions(const cvf::Vec3st& gridPointDimensions); void setResultInfo(size_t resultCount, size_t timeStepCount); + void enableWellData(bool enableWellData); void addLocalGridRefinement(const cvf::Vec3st& minCellPosition, const cvf::Vec3st& maxCellPosition, const cvf::Vec3st& singleCellRefinementFactors); diff --git a/ApplicationCode/ProjectDataModel/RimDefines.h b/ApplicationCode/ProjectDataModel/RimDefines.h index d39cb86dcb..ee90527161 100644 --- a/ApplicationCode/ProjectDataModel/RimDefines.h +++ b/ApplicationCode/ProjectDataModel/RimDefines.h @@ -46,6 +46,7 @@ class RimDefines static QString mockModelBasic() { return "Result Mock Debug Model Simple"; } static QString mockModelBasicWithResults() { return "Result Mock Debug Model With Results"; } static QString mockModelLargeWithResults() { return "Result Mock Debug Model Large With Results"; } + static QString mockModelCustomized() { return "Result Mock Debug Model Customized"; } static QString mockModelBasicInputCase() { return "Input Mock Debug Model Simple"; } diff --git a/ApplicationCode/ProjectDataModel/RimInputCase.cpp b/ApplicationCode/ProjectDataModel/RimInputCase.cpp index 42a130e15b..469730a82a 100644 --- a/ApplicationCode/ProjectDataModel/RimInputCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimInputCase.cpp @@ -77,7 +77,7 @@ RimInputCase::~RimInputCase() //-------------------------------------------------------------------------------------------------- void RimInputCase::openDataFileSet(const QStringList& fileNames) { - if (fileNames.contains("Input Mock Debug Model Simple")) + if (fileNames.contains(RimDefines::mockModelBasicInputCase())) { cvf::ref readerInterface = this->createMockModel(fileNames[0]); results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); @@ -182,7 +182,7 @@ bool RimInputCase::openEclipseGridFile() { cvf::ref readerInterface; - if (m_gridFileName().contains("Input Mock Debug Model Simple")) + if (m_gridFileName().contains(RimDefines::mockModelBasicInputCase())) { readerInterface = this->createMockModel(this->m_gridFileName()); } @@ -370,7 +370,7 @@ cvf::ref RimInputCase::createMockModel(QString modelName) cvf::ref reservoir = new RigCaseData; cvf::ref mockFileInterface = new RifReaderMockModel; - if (modelName == "Input Mock Debug Model Simple") + if (modelName == RimDefines::mockModelBasicInputCase()) { m_gridFileName = modelName; diff --git a/ApplicationCode/ProjectDataModel/RimResultCase.cpp b/ApplicationCode/ProjectDataModel/RimResultCase.cpp index 7118479742..a9a871e03b 100644 --- a/ApplicationCode/ProjectDataModel/RimResultCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultCase.cpp @@ -44,6 +44,7 @@ #include "Rim3dOverlayInfoConfig.h" #include "RimOilField.h" #include "RimAnalysisModels.h" +#include "RimMockModelSettings.h" CAF_PDM_SOURCE_INIT(RimResultCase, "EclipseCase"); //-------------------------------------------------------------------------------------------------- @@ -255,6 +256,32 @@ cvf::ref RimResultCase::createMockModel(QString modelName) mockFileInterface->open("", reservoir.p()); } + else if (modelName == RimDefines::mockModelCustomized()) + { + RimMockModelSettings rimMockModelSettings; + + //caf::Settings::readFieldsFromApplicationStore(&rimMockModelSettings); + + double startX = 0; + double startY = 0; + double startZ = 0; + + double widthX = 6000; + double widthY = 12000; + double widthZ = 500; + + // Test code to simulate UTM coordinates + double offsetX = 400000; + double offsetY = 6000000; + double offsetZ = 0; + + mockFileInterface->setWorldCoordinates(cvf::Vec3d(startX + offsetX, startY + offsetY, startZ + offsetZ), cvf::Vec3d(startX + widthX + offsetX, startY + widthY + offsetY, startZ + widthZ + offsetZ)); + mockFileInterface->setGridPointDimensions(cvf::Vec3st(rimMockModelSettings.cellCountX, rimMockModelSettings.cellCountX, rimMockModelSettings.cellCountX)); + mockFileInterface->setResultInfo(rimMockModelSettings.resultCount, rimMockModelSettings.timeStepCount); + mockFileInterface->enableWellData(false); + + mockFileInterface->open("", reservoir.p()); + } this->setReservoirData( reservoir.p() ); diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index 9cf94b5d4f..b389bed378 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -199,6 +199,7 @@ void RiuMainWindow::createActions() m_mockModelAction = new QAction("&Mock Model", this); m_mockResultsModelAction = new QAction("Mock Model With &Results", this); m_mockLargeResultsModelAction = new QAction("Large Mock Model", this); + m_mockModelCustomizedAction = new QAction("Customized Mock Model", this); m_mockInputModelAction = new QAction("Input Mock Model", this); m_snapshotToFile = new QAction(QIcon(":/SnapShotSave.png"), "Snapshot To File", this); @@ -226,6 +227,7 @@ void RiuMainWindow::createActions() connect(m_mockModelAction, SIGNAL(triggered()), SLOT(slotMockModel())); connect(m_mockResultsModelAction, SIGNAL(triggered()), SLOT(slotMockResultsModel())); connect(m_mockLargeResultsModelAction, SIGNAL(triggered()), SLOT(slotMockLargeResultsModel())); + connect(m_mockModelCustomizedAction, SIGNAL(triggered()), SLOT(slotMockModelCustomized())); connect(m_mockInputModelAction, SIGNAL(triggered()), SLOT(slotInputMockModel())); connect(m_snapshotToFile, SIGNAL(triggered()), SLOT(slotSnapshotToFile())); @@ -379,6 +381,7 @@ void RiuMainWindow::createMenus() testMenu->addAction(m_mockModelAction); testMenu->addAction(m_mockResultsModelAction); testMenu->addAction(m_mockLargeResultsModelAction); + testMenu->addAction(m_mockModelCustomizedAction); testMenu->addAction(m_mockInputModelAction); testMenu->addSeparator(); testMenu->addAction(m_createCommandObject); @@ -836,8 +839,6 @@ void RiuMainWindow::slotMockModel() { RiaApplication* app = RiaApplication::instance(); app->createMockModel(); - - //m_mainViewer->setDefaultView(); } //-------------------------------------------------------------------------------------------------- @@ -847,8 +848,6 @@ void RiuMainWindow::slotMockResultsModel() { RiaApplication* app = RiaApplication::instance(); app->createResultsMockModel(); - - //m_mainViewer->setDefaultView(); } @@ -861,6 +860,14 @@ void RiuMainWindow::slotMockLargeResultsModel() app->createLargeResultsMockModel(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMainWindow::slotMockModelCustomized() +{ + RiaApplication* app = RiaApplication::instance(); + app->createMockModelCustomized(); +} //-------------------------------------------------------------------------------------------------- /// diff --git a/ApplicationCode/UserInterface/RiuMainWindow.h b/ApplicationCode/UserInterface/RiuMainWindow.h index 631c44303c..684d39cf0c 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.h +++ b/ApplicationCode/UserInterface/RiuMainWindow.h @@ -153,6 +153,7 @@ class RiuMainWindow : public QMainWindow QAction* m_mockModelAction; QAction* m_mockResultsModelAction; QAction* m_mockLargeResultsModelAction; + QAction* m_mockModelCustomizedAction; QAction* m_mockInputModelAction; QAction* m_snapshotToFile; @@ -240,6 +241,7 @@ private slots: void slotMockModel(); void slotMockResultsModel(); void slotMockLargeResultsModel(); + void slotMockModelCustomized(); void slotInputMockModel(); // Windows slots From 78b6f200b1b6fa610ae34dddab71524f11b37c86 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 11:55:34 +0100 Subject: [PATCH 006/130] Added default editor for quint64 --- Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp index 822d2c3185..5bfee7de4f 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp @@ -65,10 +65,11 @@ CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, QString); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, int); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, double); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, float); +CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, quint64); + CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); - CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); From b3f36df480357d93105b911948a025e81f7feab7 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 11:58:49 +0100 Subject: [PATCH 007/130] Added property dialog --- Fwk/AppFwk/cafUserInterface/CMakeLists.txt | 3 + .../cafPdmUiPropertyDialog.cpp | 92 +++++++++++++++++++ .../cafUserInterface/cafPdmUiPropertyDialog.h | 70 ++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.cpp create mode 100644 Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.h diff --git a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt index 61b9318fb9..b318062071 100644 --- a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt +++ b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt @@ -26,6 +26,7 @@ set( QOBJECT_HEADERS cafPdmUiColorEditor.h cafPdmUiPropertyView.h + cafPdmUiPropertyDialog.h cafPdmUiTreeView.h cafPdmUiListView.h cafPdmUiListViewEditor.h @@ -59,6 +60,8 @@ add_library( ${PROJECT_NAME} cafPdmUiListViewEditor.cpp cafPdmUiListViewEditor.h cafPdmUiListView.cpp + cafPdmUiPropertyDialog.cpp + cafPdmUiPropertyDialog.h cafPdmUiPropertyView.cpp cafPdmUiPropertyView.h cafPdmUiPushButtonEditor.cpp diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.cpp new file mode 100644 index 0000000000..277dc3153d --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.cpp @@ -0,0 +1,92 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmUiPropertyDialog.h" + +#include "cafPdmObject.h" +#include "cafPdmUiPropertyView.h" + +#include +#include + +#include + + + +namespace caf { + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiPropertyDialog::PdmUiPropertyDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle) + : QDialog(parent) +{ + assert(object); + + m_pdmObject = object; + m_windowTitle = windowTitle; + + setupUi(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiPropertyDialog::setupUi() +{ + setWindowTitle(m_windowTitle); + + m_pdmUiPropertyView = new caf::PdmUiPropertyView(this); + + QVBoxLayout* dialogLayout = new QVBoxLayout; + setLayout(dialogLayout); + + dialogLayout->addWidget(m_pdmUiPropertyView); + m_pdmUiPropertyView->showProperties(m_pdmObject); + + // Buttons + QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + dialogLayout->addWidget(buttonBox); + + this->resize(400, 200); +} + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.h new file mode 100644 index 0000000000..4c4ca7b797 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.h @@ -0,0 +1,70 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include + +namespace caf +{ + class PdmObject; + class PdmUiPropertyView; + + +//================================================================================================== +// +// +// +//================================================================================================== +class PdmUiPropertyDialog : public QDialog +{ + Q_OBJECT + +public: + PdmUiPropertyDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle); + +private: + void setupUi(); + +private: + QString m_windowTitle; + caf::PdmObject* m_pdmObject; + caf::PdmUiPropertyView* m_pdmUiPropertyView; +}; + + +} // end namespace caf From ae381289692a1aad4c6792676fbef34e94ce1cf2 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 12:05:06 +0100 Subject: [PATCH 008/130] Improved mock model settings and use caf property dialog --- .../ProjectDataModel/RimMockModelSettings.cpp | 6 +- .../ProjectDataModel/RimResultCase.cpp | 56 ++++++++++++------- 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp b/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp index 3e032f107a..1266629d4e 100644 --- a/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp +++ b/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp @@ -35,7 +35,7 @@ RimMockModelSettings::RimMockModelSettings() CAF_PDM_InitField(&cellCountX, "CellCountX", quint64(100), "Cell Count X", "", "", ""); CAF_PDM_InitField(&cellCountY, "CellCountY", quint64(100), "Cell Count Y", "", "", ""); - CAF_PDM_InitField(&cellCountZ, "CellCountZ", quint64(100), "Cell Count Z", "", "", ""); + CAF_PDM_InitField(&cellCountZ, "CellCountZ", quint64(10), "Cell Count Z", "", "", ""); CAF_PDM_InitFieldNoDefault(&totalCellCount, "TotalCellCount", "Total Cell Count", "", "", ""); totalCellCount.setUiReadOnly(true); @@ -70,4 +70,8 @@ void RimMockModelSettings::defineUiOrdering(QString uiConfigName, caf::PdmUiOrde gridSizeGroup->add(&cellCountY); gridSizeGroup->add(&cellCountZ); gridSizeGroup->add(&totalCellCount); + + caf::PdmUiGroup* resultGroup = uiOrdering.addNewGroup("Results"); + resultGroup->add(&resultCount); + resultGroup->add(&timeStepCount); } diff --git a/ApplicationCode/ProjectDataModel/RimResultCase.cpp b/ApplicationCode/ProjectDataModel/RimResultCase.cpp index a9a871e03b..d75aebbc8e 100644 --- a/ApplicationCode/ProjectDataModel/RimResultCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultCase.cpp @@ -17,6 +17,13 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RiaStdInclude.h" + +#include "cafProgressInfo.h" +#include "cafPdmSettings.h" +#include "cafPdmFieldCvfMat4d.h" +#include "cafPdmFieldCvfColor.h" +#include "cafPdmUiPropertyDialog.h" + #include "RimResultCase.h" #include "RigCaseData.h" #include "RifReaderEclipseOutput.h" @@ -24,7 +31,7 @@ #include "RimReservoirView.h" #include "RifReaderMockModel.h" #include "RifReaderEclipseInput.h" -#include "cafProgressInfo.h" + #include "RimProject.h" #include "RifEclipseOutputFileTools.h" #include "RiaApplication.h" @@ -34,8 +41,6 @@ #include "RimReservoirCellResultsCacher.h" #include "RimWellPathCollection.h" -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" #include "RimResultSlot.h" #include "RimCellEdgeResultSlot.h" #include "RimCellRangeFilterCollection.h" @@ -258,29 +263,42 @@ cvf::ref RimResultCase::createMockModel(QString modelName) } else if (modelName == RimDefines::mockModelCustomized()) { + QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); + RimMockModelSettings rimMockModelSettings; + caf::Settings::readFieldsFromApplicationStore(&rimMockModelSettings); - //caf::Settings::readFieldsFromApplicationStore(&rimMockModelSettings); + caf::PdmUiPropertyDialog propertyDialog(NULL, &rimMockModelSettings, "Customize Mock Model"); + if (propertyDialog.exec() == QDialog::Accepted) + { + QApplication::restoreOverrideCursor(); - double startX = 0; - double startY = 0; - double startZ = 0; + caf::Settings::writeFieldsToApplicationStore(&rimMockModelSettings); - double widthX = 6000; - double widthY = 12000; - double widthZ = 500; + double startX = 0; + double startY = 0; + double startZ = 0; - // Test code to simulate UTM coordinates - double offsetX = 400000; - double offsetY = 6000000; - double offsetZ = 0; + double widthX = 6000; + double widthY = 12000; + double widthZ = 500; - mockFileInterface->setWorldCoordinates(cvf::Vec3d(startX + offsetX, startY + offsetY, startZ + offsetZ), cvf::Vec3d(startX + widthX + offsetX, startY + widthY + offsetY, startZ + widthZ + offsetZ)); - mockFileInterface->setGridPointDimensions(cvf::Vec3st(rimMockModelSettings.cellCountX, rimMockModelSettings.cellCountX, rimMockModelSettings.cellCountX)); - mockFileInterface->setResultInfo(rimMockModelSettings.resultCount, rimMockModelSettings.timeStepCount); - mockFileInterface->enableWellData(false); + // Test code to simulate UTM coordinates + double offsetX = 400000; + double offsetY = 6000000; + double offsetZ = 0; - mockFileInterface->open("", reservoir.p()); + mockFileInterface->setWorldCoordinates(cvf::Vec3d(startX + offsetX, startY + offsetY, startZ + offsetZ), cvf::Vec3d(startX + widthX + offsetX, startY + widthY + offsetY, startZ + widthZ + offsetZ)); + mockFileInterface->setGridPointDimensions(cvf::Vec3st(rimMockModelSettings.cellCountX + 1, rimMockModelSettings.cellCountY + 1, rimMockModelSettings.cellCountZ + 1)); + mockFileInterface->setResultInfo(rimMockModelSettings.resultCount, rimMockModelSettings.timeStepCount); + mockFileInterface->enableWellData(false); + + mockFileInterface->open("", reservoir.p()); + } + else + { + QApplication::restoreOverrideCursor(); + } } this->setReservoirData( reservoir.p() ); From c0c78c8ada062aecfda153edb1233ef0c66c46e9 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 12:50:39 +0100 Subject: [PATCH 009/130] Use caf property dialog and removed obsolete riuPreferencesDialog --- ApplicationCode/CMakeLists.txt | 2 - .../ProjectDataModel/RimUiTreeView.cpp | 15 ++--- .../UserInterface/RiuMainWindow.cpp | 8 +-- .../UserInterface/RiuPreferencesDialog.cpp | 67 ------------------- .../UserInterface/RiuPreferencesDialog.h | 49 -------------- 5 files changed, 11 insertions(+), 130 deletions(-) delete mode 100644 ApplicationCode/UserInterface/RiuPreferencesDialog.cpp delete mode 100644 ApplicationCode/UserInterface/RiuPreferencesDialog.h diff --git a/ApplicationCode/CMakeLists.txt b/ApplicationCode/CMakeLists.txt index be82147d67..6d0abc01cc 100644 --- a/ApplicationCode/CMakeLists.txt +++ b/ApplicationCode/CMakeLists.txt @@ -42,7 +42,6 @@ set( APPLICATION_FILES set( USER_INTERFACE_FILES UserInterface/RiuCursors.cpp UserInterface/RiuMainWindow.cpp - UserInterface/RiuPreferencesDialog.cpp UserInterface/RiuResultInfoPanel.cpp UserInterface/RiuViewer.cpp UserInterface/RiuSimpleHistogramWidget.cpp @@ -97,7 +96,6 @@ set ( QT_MOC_HEADERS ProjectDataModel/RimMimeData.h UserInterface/RiuMainWindow.h - UserInterface/RiuPreferencesDialog.h UserInterface/RiuResultInfoPanel.h UserInterface/RiuViewer.h UserInterface/RiuProcessMonitor.h diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp b/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp index f8c96f3653..af65cdb029 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp +++ b/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp @@ -19,6 +19,9 @@ //#include "RiaStdInclude.h" #include "cafPdmDocument.h" +#include "cafPdmFieldCvfColor.h" +#include "cafPdmFieldCvfMat4d.h" +#include "cafPdmUiPropertyDialog.h" #include #include @@ -37,7 +40,6 @@ #include "RimInputPropertyCollection.h" #include "RimExportInputPropertySettings.h" #include "RiaPreferences.h" -#include "RiuPreferencesDialog.h" #include "RifEclipseInputFileTools.h" #include "RimInputCase.h" #include "RimBinaryExportSettings.h" @@ -59,9 +61,6 @@ #include "RimWellPathCollection.h" #include "RimReservoirCellResultsCacher.h" #include "Rim3dOverlayInfoConfig.h" - -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" #include "RimProject.h" #include "RimOilField.h" #include "RimAnalysisModels.h" @@ -834,8 +833,8 @@ void RimUiTreeView::slotWriteInputProperty() exportSettings.fileName = outputFileName; } - RiuPreferencesDialog preferencesDialog(this, &exportSettings, "Export Eclipse Property to Text File"); - if (preferencesDialog.exec() == QDialog::Accepted) + caf::PdmUiPropertyDialog propertyDialog(this, &exportSettings, "Export Eclipse Property to Text File"); + if (propertyDialog.exec() == QDialog::Accepted) { bool isOk = RifEclipseInputFileTools::writePropertyToTextFile(exportSettings.fileName, inputReservoir->reservoirData(), 0, inputProperty->resultName, exportSettings.eclipseKeyword); if (isOk) @@ -887,8 +886,8 @@ void RimUiTreeView::slotWriteBinaryResultAsInputProperty() exportSettings.fileName = outputFileName; } - RiuPreferencesDialog preferencesDialog(this, &exportSettings, "Export Binary Eclipse Data to Text File"); - if (preferencesDialog.exec() == QDialog::Accepted) + caf::PdmUiPropertyDialog propertyDialog(this, &exportSettings, "Export Binary Eclipse Data to Text File"); + if (propertyDialog.exec() == QDialog::Accepted) { size_t timeStep = resultSlot->reservoirView()->currentTimeStep(); RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultSlot->porosityModel()); diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index b389bed378..bb99acd830 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -43,7 +43,6 @@ #include "RiuMultiCaseImportDialog.h" #include "RiaPreferences.h" -#include "RiuPreferencesDialog.h" #include "RigCaseCellResultsData.h" @@ -63,6 +62,7 @@ #include "RimCalcScript.h" #include "RimTools.h" #include "RiaRegressionTest.h" +#include "cafPdmUiPropertyDialog.h" @@ -1214,8 +1214,8 @@ void RiuMainWindow::slotShowPerformanceInfo(bool enable) void RiuMainWindow::slotEditPreferences() { RiaApplication* app = RiaApplication::instance(); - RiuPreferencesDialog preferencesDialog(this, app->preferences(), "Preferences"); - if (preferencesDialog.exec() == QDialog::Accepted) + caf::PdmUiPropertyDialog propertyDialog(this, app->preferences(), "Preferences"); + if (propertyDialog.exec() == QDialog::Accepted) { // Write preferences using QSettings and apply them to the application app->writeFieldsToApplicationStore(app->preferences()); @@ -1739,7 +1739,7 @@ void RiuMainWindow::slotShowRegressionTestDialog() RiaApplication* app = RiaApplication::instance(); app->readFieldsFromApplicationStore(®TestConfig); - RiuPreferencesDialog regressionTestDialog(this, ®TestConfig, "Regression Test"); + caf::PdmUiPropertyDialog regressionTestDialog(this, ®TestConfig, "Regression Test"); if (regressionTestDialog.exec() == QDialog::Accepted) { // Write preferences using QSettings and apply them to the application diff --git a/ApplicationCode/UserInterface/RiuPreferencesDialog.cpp b/ApplicationCode/UserInterface/RiuPreferencesDialog.cpp deleted file mode 100644 index 7a094776c8..0000000000 --- a/ApplicationCode/UserInterface/RiuPreferencesDialog.cpp +++ /dev/null @@ -1,67 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#include "RiaStdInclude.h" -#include "RiuPreferencesDialog.h" - -#include "cafAppEnum.h" -#include "cafPdmObject.h" - -#include "RimUiTreeModelPdm.h" -#include "cafPdmUiPropertyView.h" - - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RiuPreferencesDialog::RiuPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle) - : QDialog(parent) -{ - CVF_ASSERT(object); - - m_pdmObject = object; - m_windowTitle = windowTitle; - - setupUi(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuPreferencesDialog::setupUi() -{ - setWindowTitle(m_windowTitle); - - m_pdmUiPropertyView = new caf::PdmUiPropertyView(this); - - QVBoxLayout* dialogLayout = new QVBoxLayout; - setLayout(dialogLayout); - - dialogLayout->addWidget(m_pdmUiPropertyView); - m_pdmUiPropertyView->showProperties(m_pdmObject); - - // Buttons - QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - dialogLayout->addWidget(buttonBox); - - this->resize(400, 200); -} diff --git a/ApplicationCode/UserInterface/RiuPreferencesDialog.h b/ApplicationCode/UserInterface/RiuPreferencesDialog.h deleted file mode 100644 index 3751e108fb..0000000000 --- a/ApplicationCode/UserInterface/RiuPreferencesDialog.h +++ /dev/null @@ -1,49 +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 - -namespace caf -{ - class PdmObject; - class PdmUiPropertyView; -} - - -//================================================================================================== -// -// -// -//================================================================================================== -class RiuPreferencesDialog : public QDialog -{ - Q_OBJECT - -public: - RiuPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle); - -private: - void setupUi(); - -private: - QString m_windowTitle; - caf::PdmObject* m_pdmObject; - caf::PdmUiPropertyView* m_pdmUiPropertyView; -}; From e47f2e6317c04a776d9af83acc443af499585f55 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 8 Nov 2013 10:34:05 +0100 Subject: [PATCH 010/130] Performance: Added OpenMP to mock models --- .../RigReservoirBuilderMock.cpp | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp index 7c1f5a203e..d99f6d1a2d 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp @@ -135,10 +135,14 @@ void RigReservoirBuilderMock::appendCubeNodes(const cvf::Vec3d& min, const cvf:: void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCount, RigGridBase* hostGrid, std::vector& cells) { size_t activeCellIndex = 0; - size_t i; - for (i = 0; i < cellCount; i++) + long long i; + + cells.resize(cellCount); + +#pragma omp parallel for + for (i = 0; i < static_cast(cellCount); i++) { - RigCell riCell; + RigCell& riCell = cells[i]; riCell.setHostGrid(hostGrid); riCell.setCellIndex(i); @@ -165,8 +169,6 @@ void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCoun riCell.setActiveIndexInMatrixModel(activeCellIndex++); } */ - - cells.push_back(riCell); } } @@ -348,13 +350,15 @@ bool RigReservoirBuilderMock::dynamicResult(RigCaseData* eclipseCase, const QStr double scaleValue = 1.0 + resultIndex * 0.1; double offsetValue = 100 * resultIndex; - size_t k; - for (k = 0; k < eclipseCase->mainGrid()->cells().size(); k++) + values->resize(eclipseCase->mainGrid()->cells().size()); + +#pragma omp parallel for + for (long long k = 0; k < static_cast(eclipseCase->mainGrid()->cells().size()); k++) { RigCell& cell = eclipseCase->mainGrid()->cells()[k]; { double val = offsetValue + scaleValue * ( (stepIndex * 1000 + k) % eclipseCase->mainGrid()->cells().size() ); - values->push_back(val); + values->at(k) = val; } } From 4d467447837906451e5be17c81ec9653f435649e Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 8 Nov 2013 14:27:21 +0100 Subject: [PATCH 011/130] Performance: Reduce memory use for riGetPropertyData --- .../SocketInterface/RiaPropertyDataCommands.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index 40dc5d2efd..f31218d7e3 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -304,10 +304,10 @@ class RiaGetGridProperty: public RiaSocketCommand quint64 timestepCount = (quint64)requestedTimesteps.size(); socketStream << timestepCount; - size_t doubleValueCount = cellCountI * cellCountJ * cellCountK * timestepCount * sizeof(double); - std::vector values(doubleValueCount); size_t valueIdx = 0; + std::vector values(rigGrid->cellCount()); + for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); @@ -323,11 +323,11 @@ class RiaGetGridProperty: public RiaSocketCommand { cellValue = 0.0; } - values[valueIdx++] = cellValue; + values[cellIdx] = cellValue; } - } - server->currentClient()->write((const char *)values.data(), doubleValueCount); + server->currentClient()->write((const char *)values.data(), rigGrid->cellCount() * sizeof(double)); + } return true; } From f4559008ba513f617f0bfcdb4604b2e253c74f09 Mon Sep 17 00:00:00 2001 From: magnesj Date: Mon, 11 Nov 2013 14:36:59 +0100 Subject: [PATCH 012/130] Temporarily fixes for handling communication of more than 2GB data to/from octave --- OctavePlugin/riGetActiveCellProperty.cpp | 4 +- OctavePlugin/riGetGridProperty.cpp | 85 +++++++++++++++++++++--- OctavePlugin/riSetGridProperty.cpp | 13 ++-- 3 files changed, 87 insertions(+), 15 deletions(-) diff --git a/OctavePlugin/riGetActiveCellProperty.cpp b/OctavePlugin/riGetActiveCellProperty.cpp index a936b82d96..81b966f7d0 100644 --- a/OctavePlugin/riGetActiveCellProperty.cpp +++ b/OctavePlugin/riGetActiveCellProperty.cpp @@ -67,7 +67,7 @@ void getActiveCellProperty(Matrix& propertyFrames, const QString &serverName, qu for (size_t tIdx = 0; tIdx < timestepCount; ++tIdx) { - while (socket.bytesAvailable() < (int)byteCount) + while (socket.bytesAvailable() < (qint64)byteCount) { if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) { @@ -94,7 +94,7 @@ void getActiveCellProperty(Matrix& propertyFrames, const QString &serverName, qu } #endif - if ((int)byteCount != bytesRead) + if ((qint64)byteCount != bytesRead) { error("Could not read binary double data properly from socket"); octave_stdout << "Active cells: " << activeCellCount << ", Timesteps: " << timestepCount << std::endl; diff --git a/OctavePlugin/riGetGridProperty.cpp b/OctavePlugin/riGetGridProperty.cpp index 3771341644..3b1fbc589f 100644 --- a/OctavePlugin/riGetGridProperty.cpp +++ b/OctavePlugin/riGetGridProperty.cpp @@ -22,7 +22,7 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 QString command; command += "GetGridProperty " + QString::number(caseId) + " " + QString::number(gridIdx) + " " + propertyName + " " + porosityModel; - for (int i = 0; i < requestedTimeSteps.length(); ++i) + for (qint64 i = 0; i < requestedTimeSteps.length(); ++i) { if (i == 0) command += " "; command += QString::number(static_cast(requestedTimeSteps.elem(i)) - 1); // To make the index 0-based @@ -36,7 +36,7 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 // Get response. First wait for the header - while (socket.bytesAvailable() < (int)(4*sizeof(quint64))) + while (socket.bytesAvailable() < (qint64)(4*sizeof(quint64))) { if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) { @@ -48,6 +48,7 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 // Read sizes quint64 totalByteCount; + quint64 cellCountI; quint64 cellCountJ; quint64 cellCountK; @@ -59,6 +60,9 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 socketStream >> timestepCount; totalByteCount = cellCountI*cellCountJ*cellCountK*timestepCount*sizeof(double); + + qint64 timestepByteCount = cellCountI*cellCountJ*cellCountK*sizeof(double); + if (!(totalByteCount)) { error ("Could not find the requested data in ResInsight"); @@ -75,29 +79,92 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 propertyFrames.resize(dv); - // Wait for available data +#if 1 + // Wait for available data for each timestep, then read data for each timestep + + qint64 totalBytesRead = 0; + + for (size_t tIdx = 0; tIdx < timestepCount; ++tIdx) + { + qint64 bytesAvailable = socket.bytesAvailable() ; + + while ( bytesAvailable < (qint64)timestepByteCount) + { + if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) + { + error((("Waiting for timestep data number: ") + QString::number(tIdx)+ ": " + socket.errorString()).toLatin1().data()); + octave_stdout << "Cellcount: " << cellCountI*cellCountJ*cellCountK << ", Timesteps: " << timestepCount << std::endl; + return ; + } + + bytesAvailable = socket.bytesAvailable(); + + OCTAVE_QUIT; + } - while (socket.bytesAvailable() < (int)totalByteCount) + qint64 bytesRead = 0; + double * internalMatrixData = propertyFrames.fortran_vec(); + + // Raw data transfer. Faster. Not possible when dealing with coarsening + bytesRead = socket.read(((char*)(internalMatrixData)) + tIdx * timestepByteCount, timestepByteCount); + + if ((qint64)timestepByteCount != bytesRead) + { + error("Could not read binary double data properly from socket"); + octave_stdout << "Cellcount: " << cellCountI*cellCountJ*cellCountK << ", Timesteps count: " << timestepCount << std::endl; + octave_stdout << "Timestep : " << tIdx << std::endl; + } + + totalBytesRead += bytesRead; + + OCTAVE_QUIT; + } + + if ((qint64)totalByteCount != totalBytesRead) { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) + error("Could not read binary double data properly from socket"); + } + + #else + + // Wait for available data + qint64 bytesAvailable = socket.bytesAvailable() ; + + while (bytesAvailable < (qint64)totalByteCount) + { + octave_stdout << "Waiting for data. Has : " << bytesAvailable << " Needs :" << totalByteCount << std::endl; + if (!socket.waitForReadyRead(riOctavePlugin::shortTimeOutMilliSecs)) { - error(("Waiting for data : " + socket.errorString()).toLatin1().data()); - return ; + //error(("Waiting for data : " + socket.errorString()).toLatin1().data()); + //return ; } + + bytesAvailable = socket.bytesAvailable() ; OCTAVE_QUIT; } qint64 bytesRead = 0; double * internalMatrixData = propertyFrames.fortran_vec(); +#if 0 + + char* dataBuffer = new char[totalByteCount]; + bytesRead = socket.read(dataBuffer, totalByteCount); + + +#else + // Raw data transfer. Faster. bytesRead = socket.read((char*)(internalMatrixData ), totalByteCount); +#endif - if ((int)totalByteCount != bytesRead) + + if ((qint64)totalByteCount != bytesRead) { error("Could not read binary double data properly from socket"); } - + +#endif QString tmp = QString("riGetGridProperty : Read %1").arg(propertyName); if (caseId < 0) diff --git a/OctavePlugin/riSetGridProperty.cpp b/OctavePlugin/riSetGridProperty.cpp index 04773e8804..f5afe0a0f7 100644 --- a/OctavePlugin/riSetGridProperty.cpp +++ b/OctavePlugin/riSetGridProperty.cpp @@ -64,8 +64,13 @@ void setEclipseProperty(const NDArray& propertyFrames, const QString &hostName, socketStream << (qint64)singleTimeStepByteCount; const double* internalData = propertyFrames.fortran_vec(); - int dataWritten = socket.write((const char *)internalData, singleTimeStepByteCount*timeStepCount); - + qint64 dataWritten = 0; + + for (size_t tsIdx = 0; tsIdx < timeStepCount; ++tsIdx) + { + dataWritten += socket.write(((const char *)internalData) + tsIdx*singleTimeStepByteCount, singleTimeStepByteCount); + } + if (dataWritten == singleTimeStepByteCount*timeStepCount) { QString tmp = QString("riSetGridProperty : Wrote %1").arg(propertyName); @@ -92,8 +97,8 @@ void setEclipseProperty(const NDArray& propertyFrames, const QString &hostName, while(socket.bytesToWrite() && socket.state() == QAbstractSocket::ConnectedState) { - // octave_stdout << "Bytes to write: " << socket.bytesToWrite() << std::endl; - socket.waitForBytesWritten(riOctavePlugin::longTimeOutMilliSecs); + octave_stdout << "Bytes to write: " << socket.bytesToWrite() << std::endl << std::flush; + socket.waitForBytesWritten(2000); OCTAVE_QUIT; } From af6d92d64eb5c0f0d42ccb092f43593064725212 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 1 Apr 2014 13:02:52 +0200 Subject: [PATCH 013/130] Added flag to control how to do IO with sockets --- .../Application/RiaPreferences.cpp | 2 + ApplicationCode/Application/RiaPreferences.h | 2 + .../SocketInterface/RiaGeometryCommands.cpp | 62 +++++++++++++++---- .../RiaPropertyDataCommands.cpp | 55 ++++++++++++---- 4 files changed, 97 insertions(+), 24 deletions(-) diff --git a/ApplicationCode/Application/RiaPreferences.cpp b/ApplicationCode/Application/RiaPreferences.cpp index 19454642f1..bd065e418c 100644 --- a/ApplicationCode/Application/RiaPreferences.cpp +++ b/ApplicationCode/Application/RiaPreferences.cpp @@ -59,6 +59,8 @@ RiaPreferences::RiaPreferences(void) CAF_PDM_InitField(&autocomputeSOIL, "autocomputeSOIL", true, "SOIL", "", "SOIL = 1.0 - SGAS - SWAT", ""); CAF_PDM_InitField(&autocomputeDepthRelatedProperties,"autocomputeDepth", true, "DEPTH related properties", "", "DEPTH, DX, DY, DZ, TOP, BOTTOM", ""); + + CAF_PDM_InitField(&useStreamTransfer, "useStreamTransfer", true, "Use stream transfer to Octave", "", "", ""); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Application/RiaPreferences.h b/ApplicationCode/Application/RiaPreferences.h index 0f87fecc17..f877efdbb4 100644 --- a/ApplicationCode/Application/RiaPreferences.h +++ b/ApplicationCode/Application/RiaPreferences.h @@ -59,6 +59,8 @@ class RiaPreferences : public caf::PdmObject caf::PdmField autocomputeDepthRelatedProperties; + caf::PdmField useStreamTransfer; + protected: virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); diff --git a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp index 2ec5878cb6..413f4791bc 100644 --- a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp @@ -34,6 +34,8 @@ #include "RigCaseCellResultsData.h" #include +#include "RiaApplication.h" +#include "RiaPreferences.h" //-------------------------------------------------------------------------------------------------- @@ -241,32 +243,66 @@ class RiaGetCellCorners : public RiaSocketCommand // dv(3) = 8; // dv(4) = 3; - std::vector cellCornerValues(doubleValueCount); - cvf::Vec3d cornerVerts[8]; - quint64 coordCount = 0; - for (int coordIdx = 0; coordIdx < 3; coordIdx++) + cvf::Timer timer; + + if (RiaApplication::instance()->preferences()->useStreamTransfer()) { - for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) + cvf::Vec3d cornerVerts[8]; + for (int coordIdx = 0; coordIdx < 3; coordIdx++) { - size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; + for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) + { + size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; + + for (size_t k = 0; k < cellCountK; k++) + { + for (size_t j = 0; j < cellCountJ; j++) + { + for (size_t i = 0; i < cellCountI; i++) + { + size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); + rigGrid->cellCornerVertices(localCellIdx, cornerVerts); - for (size_t k = 0; k < cellCountK; k++) + socketStream << cornerVerts[cornerIndexMapping][coordIdx]; + } + } + } + } + } + } + else + { + std::vector cellCornerValues(doubleValueCount); + cvf::Vec3d cornerVerts[8]; + quint64 coordCount = 0; + for (int coordIdx = 0; coordIdx < 3; coordIdx++) + { + for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) { - for (size_t j = 0; j < cellCountJ; j++) + size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; + + for (size_t k = 0; k < cellCountK; k++) { - for (size_t i = 0; i < cellCountI; i++) + for (size_t j = 0; j < cellCountJ; j++) { - size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); - rigGrid->cellCornerVertices(localCellIdx, cornerVerts); + for (size_t i = 0; i < cellCountI; i++) + { + size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); + rigGrid->cellCornerVertices(localCellIdx, cornerVerts); - cellCornerValues[coordCount++] = cornerVerts[cornerIndexMapping][coordIdx]; + cellCornerValues[coordCount++] = cornerVerts[cornerIndexMapping][coordIdx]; + } } } } } + server->currentClient()->write((const char *)cellCornerValues.data(), byteCount); } - server->currentClient()->write((const char *)cellCornerValues.data(), byteCount); + double totalTimeMS = timer.time() * 1000.0; + QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); + + server->errorMessageDialog()->showMessage(resultInfo); return true; } diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index f31218d7e3..4fa6a4f841 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -40,6 +40,8 @@ #include "Rim3dOverlayInfoConfig.h" #include +#include "RiaApplication.h" +#include "RiaPreferences.h" //-------------------------------------------------------------------------------------------------- @@ -305,30 +307,61 @@ class RiaGetGridProperty: public RiaSocketCommand socketStream << timestepCount; size_t valueIdx = 0; - - std::vector values(rigGrid->cellCount()); + cvf::Timer timer; - for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) + if (RiaApplication::instance()->preferences()->useStreamTransfer()) { - cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); - if (cellCenterDataAccessObject.isNull()) + for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { - continue; + cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); + if (cellCenterDataAccessObject.isNull()) + { + continue; + } + + for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) + { + double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); + if (cellValue == HUGE_VAL) + { + cellValue = 0.0; + } + + socketStream << cellValue; + } } + } + else + { - for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) + std::vector values(rigGrid->cellCount()); + for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { - double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); - if (cellValue == HUGE_VAL) + cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); + if (cellCenterDataAccessObject.isNull()) { - cellValue = 0.0; + continue; + } + + for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) + { + double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); + if (cellValue == HUGE_VAL) + { + cellValue = 0.0; + } + values[valueIdx++] = cellValue; } - values[cellIdx] = cellValue; } server->currentClient()->write((const char *)values.data(), rigGrid->cellCount() * sizeof(double)); } + double totalTimeMS = timer.time() * 1000.0; + QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); + + server->errorMessageDialog()->showMessage(resultInfo); + return true; } }; From 4ab5e28cf7b4c3906363165fc35a9eb4ac569b19 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 1 Apr 2014 15:31:13 +0200 Subject: [PATCH 014/130] Added block write to socket tools --- .../Application/RiaPreferences.cpp | 1 + ApplicationCode/Application/RiaPreferences.h | 1 + .../SocketInterface/RiaCaseInfoCommands.cpp | 9 +++- .../SocketInterface/RiaGeometryCommands.cpp | 10 ++-- .../RiaPropertyDataCommands.cpp | 5 +- .../SocketInterface/RiaSocketTools.cpp | 47 +++++++++++++++++++ .../SocketInterface/RiaSocketTools.h | 3 ++ 7 files changed, 67 insertions(+), 9 deletions(-) diff --git a/ApplicationCode/Application/RiaPreferences.cpp b/ApplicationCode/Application/RiaPreferences.cpp index bd065e418c..0c63994aec 100644 --- a/ApplicationCode/Application/RiaPreferences.cpp +++ b/ApplicationCode/Application/RiaPreferences.cpp @@ -61,6 +61,7 @@ RiaPreferences::RiaPreferences(void) CAF_PDM_InitField(&autocomputeDepthRelatedProperties,"autocomputeDepth", true, "DEPTH related properties", "", "DEPTH, DX, DY, DZ, TOP, BOTTOM", ""); CAF_PDM_InitField(&useStreamTransfer, "useStreamTransfer", true, "Use stream transfer to Octave", "", "", ""); + CAF_PDM_InitField(&blockSize, "blockSize", 10000, "blockSize", "", "", ""); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Application/RiaPreferences.h b/ApplicationCode/Application/RiaPreferences.h index f877efdbb4..f46f002b35 100644 --- a/ApplicationCode/Application/RiaPreferences.h +++ b/ApplicationCode/Application/RiaPreferences.h @@ -60,6 +60,7 @@ class RiaPreferences : public caf::PdmObject caf::PdmField useStreamTransfer; + caf::PdmField blockSize; protected: virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); diff --git a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp index 201267dfb0..e6444f314d 100644 --- a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp @@ -16,9 +16,12 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RiaStdInclude.h" + #include "RiaSocketCommand.h" #include "RiaSocketServer.h" #include "RiaSocketTools.h" +#include "RiaApplication.h" +#include "RiaPreferences.h" #include "RimReservoirView.h" #include "RimResultSlot.h" @@ -28,8 +31,8 @@ #include "RimWellCollection.h" #include "Rim3dOverlayInfoConfig.h" #include "RimReservoirCellResultsCacher.h" - #include "RimCase.h" + #include "RigCaseData.h" #include "RigCaseCellResultsData.h" @@ -37,6 +40,7 @@ + //-------------------------------------------------------------------------------------------------- /// OBSOLETE, to be deleted //-------------------------------------------------------------------------------------------------- @@ -133,7 +137,8 @@ class RiaGetActiveCellInfo: public RiaSocketCommand for (size_t tIdx = 0; tIdx < columnCount; ++tIdx) { #if 1 // Write data as raw bytes, fast but does not handle byteswapping - server->currentClient()->write((const char *)activeCellInfo[tIdx].data(), timestepByteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)activeCellInfo[tIdx].data(), timestepByteCount); + #else // Write data using QDataStream, does byteswapping for us. Must use QDataStream on client as well for (size_t cIdx = 0; cIdx < activeCellInfo[tIdx].size(); ++cIdx) { diff --git a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp index 413f4791bc..5a3c8bc8b7 100644 --- a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp @@ -38,6 +38,7 @@ #include "RiaPreferences.h" + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -108,7 +109,7 @@ class RiaGetCellCenters : public RiaSocketCommand CVF_ASSERT(coordCount == doubleValueCount); - server->currentClient()->write((const char *)cellCenterValues.data(), byteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCenterValues.data(), byteCount); return true; } @@ -181,7 +182,7 @@ class RiaGetActiveCellCenters : public RiaSocketCommand quint64 byteCount = doubleValueCount * sizeof(double); socketStream << byteCount; - server->currentClient()->write((const char *)cellCenterValues.data(), byteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCenterValues.data(), byteCount); return true; } @@ -296,7 +297,8 @@ class RiaGetCellCorners : public RiaSocketCommand } } } - server->currentClient()->write((const char *)cellCornerValues.data(), byteCount); + + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCornerValues.data(), byteCount); } double totalTimeMS = timer.time() * 1000.0; @@ -381,7 +383,7 @@ class RiaGetActiveCellCorners : public RiaSocketCommand quint64 byteCount = doubleValueCount * sizeof(double); socketStream << byteCount; - server->currentClient()->write((const char *)cellCornerValues.data(), byteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCornerValues.data(), byteCount); return true; } diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index 4fa6a4f841..00210e4e21 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -334,7 +334,6 @@ class RiaGetGridProperty: public RiaSocketCommand else { - std::vector values(rigGrid->cellCount()); for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); @@ -343,6 +342,7 @@ class RiaGetGridProperty: public RiaSocketCommand continue; } + std::vector values(rigGrid->cellCount()); for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) { double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); @@ -352,9 +352,8 @@ class RiaGetGridProperty: public RiaSocketCommand } values[valueIdx++] = cellValue; } + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), values.size() * sizeof(double)); } - - server->currentClient()->write((const char *)values.data(), rigGrid->cellCount() * sizeof(double)); } double totalTimeMS = timer.time() * 1000.0; diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.cpp b/ApplicationCode/SocketInterface/RiaSocketTools.cpp index cc53f26824..4ad720d2a9 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketTools.cpp @@ -16,6 +16,10 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RiaStdInclude.h" + +#include "RiaApplication.h" +#include "RiaPreferences.h" + #include "RiaSocketTools.h" #include "RiaSocketServer.h" #include "RimCase.h" @@ -34,6 +38,8 @@ #include "RimInputPropertyCollection.h" +#include + //-------------------------------------------------------------------------------------------------- /// @@ -98,4 +104,45 @@ void RiaSocketTools::getCaseInfoFromCase(RimCase* rimCase, qint64& caseId, QStri } } +bool RiaSocketTools::writeBlockData(RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite) +{ + cvf::Timer timer; + + quint64 bytesWritten = 0; + int blockCount = 0; + + quint64 maxBlockSize = RiaApplication::instance()->preferences()->blockSize(); + + while (bytesWritten < bytesToWrite) + { + quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize); + + quint64 actuallyBytesWritten = socket->write(data + bytesWritten, byteCountToWrite); + if (actuallyBytesWritten == -1) + { + if (server) + { + QString errorMessage = "Error detected when writing data, error string from socket : \n" + socket->errorString(); + + server->errorMessageDialog()->showMessage(errorMessage); + } + + return false; + } + + bytesWritten += actuallyBytesWritten; + + blockCount++; + } + + if (server) + { + double totalTimeMS = timer.time() * 1000.0; + QString resultInfo = QString("Total time '%1 ms'\nTotal bytes written . %2\nNumber of blocks : %3\nBlock size : %4").arg(totalTimeMS).arg(bytesWritten).arg(blockCount).arg(maxBlockSize); + + server->errorMessageDialog()->showMessage(resultInfo); + } + + return true; +} diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.h b/ApplicationCode/SocketInterface/RiaSocketTools.h index 1baeb5a9fc..b331799e2e 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.h +++ b/ApplicationCode/SocketInterface/RiaSocketTools.h @@ -17,6 +17,7 @@ class RimCase; class RiaSocketServer; +class QTcpSocket; #define PMonLog( MessageString ) RiuMainWindow::instance()->processMonitor()->addStringToLog( MessageString ); @@ -25,4 +26,6 @@ class RiaSocketTools public: static RimCase* findCaseFromArgs(RiaSocketServer* server, const QList& args); static void getCaseInfoFromCase(RimCase* rimCase, qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId); + + static bool writeBlockData(RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite); }; From f5e1773fde10c245068e7ebed6a7b7c5c228229b Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 1 Apr 2014 15:36:08 +0200 Subject: [PATCH 015/130] Fixed used on unsigned --- ApplicationCode/SocketInterface/RiaSocketTools.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.cpp b/ApplicationCode/SocketInterface/RiaSocketTools.cpp index 4ad720d2a9..0f645450f9 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketTools.cpp @@ -113,12 +113,13 @@ bool RiaSocketTools::writeBlockData(RiaSocketServer* server, QTcpSocket* socket, quint64 maxBlockSize = RiaApplication::instance()->preferences()->blockSize(); + while (bytesWritten < bytesToWrite) { quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize); - quint64 actuallyBytesWritten = socket->write(data + bytesWritten, byteCountToWrite); - if (actuallyBytesWritten == -1) + qint64 actuallyBytesWritten = socket->write(data + bytesWritten, byteCountToWrite); + if (actuallyBytesWritten < 0) { if (server) { From e748f087a7741fa79d5318c83999b12715d1c7d3 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Wed, 2 Apr 2014 08:55:26 +0200 Subject: [PATCH 016/130] Added block read from socket --- .../SocketInterface/RiaSocketTools.cpp | 43 +++++++++++++++++++ .../SocketInterface/RiaSocketTools.h | 1 + OctavePlugin/riGetCellCorners.cpp | 17 ++++++++ 3 files changed, 61 insertions(+) diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.cpp b/ApplicationCode/SocketInterface/RiaSocketTools.cpp index 0f645450f9..64cc8e0c11 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketTools.cpp @@ -147,3 +147,46 @@ bool RiaSocketTools::writeBlockData(RiaSocketServer* server, QTcpSocket* socket, return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiaSocketTools::readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages) +{ + quint64 bytesRead = 0; + int blockCount = 0; + + quint64 maxBlockSize = RiaApplication::instance()->preferences()->blockSize(); + + while (bytesRead < bytesToRead) + { + if (socket.bytesAvailable()) + { + quint64 byteCountToRead = qMin(bytesToRead - bytesRead, maxBlockSize); + + qint64 actuallyBytesRead = socket.read(data + bytesRead, byteCountToRead); + if (actuallyBytesRead < 0) + { + errorMessages.push_back("Error detected when writing data, error string from socket"); + errorMessages.push_back(socket.errorString()); + + return false; + } + + bytesRead += actuallyBytesRead; + blockCount++; + } + else + { + if (!socket.waitForReadyRead()) + { + errorMessages.push_back("Waited for data for %1 milli seconds."); + errorMessages.push_back(socket.errorString()); + + return false; + } + } + } + + return true; +} + diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.h b/ApplicationCode/SocketInterface/RiaSocketTools.h index b331799e2e..5a24731237 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.h +++ b/ApplicationCode/SocketInterface/RiaSocketTools.h @@ -28,4 +28,5 @@ class RiaSocketTools static void getCaseInfoFromCase(RimCase* rimCase, qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId); static bool writeBlockData(RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite); + static bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages); }; diff --git a/OctavePlugin/riGetCellCorners.cpp b/OctavePlugin/riGetCellCorners.cpp index ee8f810239..af659079c0 100644 --- a/OctavePlugin/riGetCellCorners.cpp +++ b/OctavePlugin/riGetCellCorners.cpp @@ -1,7 +1,10 @@ #include +#include + #include #include "riSettings.h" +#include "../ApplicationCode/SocketInterface/RiaSocketTools.h" void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 port, const qint32& caseId, const quint32& gridIndex) @@ -67,7 +70,20 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 dv(4) = 3; cellCornerValues.resize(dv); + double* internalMatrixData = cellCornerValues.fortran_vec(); + QStringList errorMessages; + if (!RiaSocketTools::readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) + { + for (int i = 0; i < errorMessages.size(); i++) + { + error(errorMessages[i].toLatin1().data()); + } + + OCTAVE_QUIT; + } + + /* while (socket.bytesAvailable() < (qint64)(byteCount)) { if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) @@ -97,6 +113,7 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 } #endif + */ return; } From ecf00881986dbf853395af5be2dd0a35f346b326 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Wed, 2 Apr 2014 09:52:02 +0200 Subject: [PATCH 017/130] Moved Octave socket reading into riSocketTools --- OctavePlugin/riGetCellCorners.cpp | 8 ++++-- OctavePlugin/riGetCurrentCase.cpp | 1 + OctavePlugin/riSocketTools.h | 46 +++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 OctavePlugin/riSocketTools.h diff --git a/OctavePlugin/riGetCellCorners.cpp b/OctavePlugin/riGetCellCorners.cpp index af659079c0..f5e3b2c356 100644 --- a/OctavePlugin/riGetCellCorners.cpp +++ b/OctavePlugin/riGetCellCorners.cpp @@ -4,7 +4,9 @@ #include #include "riSettings.h" -#include "../ApplicationCode/SocketInterface/RiaSocketTools.h" +#include "riSocketTools.h" + + void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 port, const qint32& caseId, const quint32& gridIndex) @@ -72,7 +74,7 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 double* internalMatrixData = cellCornerValues.fortran_vec(); QStringList errorMessages; - if (!RiaSocketTools::readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) + if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) { for (int i = 0; i < errorMessages.size(); i++) { @@ -82,6 +84,8 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 OCTAVE_QUIT; } + octave_stdout << "Bytes count processed : " << byteCount << std::endl; + /* while (socket.bytesAvailable() < (qint64)(byteCount)) diff --git a/OctavePlugin/riGetCurrentCase.cpp b/OctavePlugin/riGetCurrentCase.cpp index 80b0ffe4ac..88cc38088d 100644 --- a/OctavePlugin/riGetCurrentCase.cpp +++ b/OctavePlugin/riGetCurrentCase.cpp @@ -3,6 +3,7 @@ #include #include "riSettings.h" +#include "riSocketTools.h" void getCurrentCase(qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId, const QString &hostName, quint16 port) { diff --git a/OctavePlugin/riSocketTools.h b/OctavePlugin/riSocketTools.h new file mode 100644 index 0000000000..7d01381668 --- /dev/null +++ b/OctavePlugin/riSocketTools.h @@ -0,0 +1,46 @@ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages) +{ + quint64 bytesRead = 0; + int blockCount = 0; + + quint64 maxBlockSize = 100000; + + while (bytesRead < bytesToRead) + { + if (socket.bytesAvailable()) + { + quint64 byteCountToRead = qMin(bytesToRead - bytesRead, maxBlockSize); + + qint64 actuallyBytesRead = socket.read(data + bytesRead, byteCountToRead); + if (actuallyBytesRead < 0) + { + errorMessages.push_back("Error detected when writing data, error string from socket"); + errorMessages.push_back(socket.errorString()); + + return false; + } + + bytesRead += actuallyBytesRead; + + octave_stdout << "Bytes read " << bytesRead << " of total " << bytesToRead << std::endl; + + blockCount++; + } + else + { + if (!socket.waitForReadyRead()) + { + errorMessages.push_back("Waited for data for %1 milli seconds."); + errorMessages.push_back(socket.errorString()); + + return false; + } + } + } + + return true; +} From f19f080fb0be4274e986a9dfea071728b1603a0d Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 3 Apr 2014 08:16:15 +0200 Subject: [PATCH 018/130] Moved socket max byte count to riSettings Added header files to cmake --- OctavePlugin/CMakeLists.txt | 5 ++++- OctavePlugin/riSettings.h | 2 ++ OctavePlugin/riSocketTools.h | 38 ++++++++++++++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/OctavePlugin/CMakeLists.txt b/OctavePlugin/CMakeLists.txt index 68a4b588d3..7a11e18ab9 100644 --- a/OctavePlugin/CMakeLists.txt +++ b/OctavePlugin/CMakeLists.txt @@ -141,7 +141,10 @@ if (RESINSIGHT_OCTAVE_PLUGIN_QMAKE AND RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE) "${CMAKE_CURRENT_BINARY_DIR}/riGetWellNames.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetWellStatus.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetWellCells.oct" - SOURCES ${CPP_SOURCES} + SOURCES + ${CPP_SOURCES} + riSocketTools.h + riSettings.h ) diff --git a/OctavePlugin/riSettings.h b/OctavePlugin/riSettings.h index bc7220e845..5765244a6d 100644 --- a/OctavePlugin/riSettings.h +++ b/OctavePlugin/riSettings.h @@ -24,6 +24,8 @@ namespace riOctavePlugin const int shortTimeOutMilliSecs = 5000; const int longTimeOutMilliSecs = 6000000; + const int socketMaxByteCount = 100000; + // Octave data structure : CaseInfo char caseInfo_CaseId[] = "CaseId"; char caseInfo_CaseName[] = "CaseName"; diff --git a/OctavePlugin/riSocketTools.h b/OctavePlugin/riSocketTools.h index 7d01381668..63cc24d890 100644 --- a/OctavePlugin/riSocketTools.h +++ b/OctavePlugin/riSocketTools.h @@ -7,7 +7,7 @@ bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringL quint64 bytesRead = 0; int blockCount = 0; - quint64 maxBlockSize = 100000; + quint64 maxBlockSize = riOctavePlugin::socketMaxByteCount; while (bytesRead < bytesToRead) { @@ -18,7 +18,7 @@ bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringL qint64 actuallyBytesRead = socket.read(data + bytesRead, byteCountToRead); if (actuallyBytesRead < 0) { - errorMessages.push_back("Error detected when writing data, error string from socket"); + errorMessages.push_back("Error detected when reading data, error string from socket :"); errorMessages.push_back(socket.errorString()); return false; @@ -41,6 +41,40 @@ bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringL } } } + + octave_stdout << "Bytes read " << bytesToRead << std::endl; + + return true; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool writeBlockData(QTcpSocket& socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages) +{ + quint64 bytesWritten = 0; + int blockCount = 0; + + quint64 maxBlockSize = riOctavePlugin::socketMaxByteCount; + + while (bytesWritten < bytesToWrite) + { + quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize); + + qint64 actuallyBytesWritten = socket.write(data + bytesWritten, byteCountToWrite); + if (actuallyBytesWritten < 0) + { + errorMessages.push_back("Error detected when writing data, error string from socket"); + errorMessages.push_back(socket.errorString()); + + return false; + } + + bytesWritten += actuallyBytesWritten; + + blockCount++; + } return true; } From 05f1c056b7c4a12af8f23738d42dd83d520f0a22 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 3 Apr 2014 10:41:27 +0200 Subject: [PATCH 019/130] Use socket block read/write for geometry data --- .../SocketInterface/RiaGeometryCommands.cpp | 127 ++++++++---------- OctavePlugin/riGetActiveCellCenters.cpp | 23 ++-- OctavePlugin/riGetActiveCellCorners.cpp | 23 ++-- OctavePlugin/riGetCellCenters.cpp | 37 ++--- OctavePlugin/riGetCellCorners.cpp | 35 ----- 5 files changed, 82 insertions(+), 163 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp index 5a3c8bc8b7..2ca72a655d 100644 --- a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp @@ -87,11 +87,14 @@ class RiaGetCellCenters : public RiaSocketCommand // dv(2) = cellCountK; // dv(3) = 3; - std::vector cellCenterValues(doubleValueCount); cvf::Vec3d cornerVerts[8]; - quint64 coordCount = 0; + size_t blockByteCount = cellCount * sizeof(double); + std::vector doubleValues(blockByteCount); + for (int coordIdx = 0; coordIdx < 3; coordIdx++) { + quint64 valueIndex = 0; + for (size_t k = 0; k < cellCountK; k++) { for (size_t j = 0; j < cellCountJ; j++) @@ -101,15 +104,15 @@ class RiaGetCellCenters : public RiaSocketCommand size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); cvf::Vec3d center = rigGrid->cell(localCellIdx).center(); - cellCenterValues[coordCount++] = center[coordIdx]; + doubleValues[valueIndex++] = center[coordIdx]; } } } - } - CVF_ASSERT(coordCount == doubleValueCount); + CVF_ASSERT(valueIndex == cellCount); - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCenterValues.data(), byteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); + } return true; } @@ -152,6 +155,11 @@ class RiaGetActiveCellCenters : public RiaSocketCommand size_t activeCellCount = actCellInfo->globalActiveCellCount(); size_t doubleValueCount = activeCellCount * 3; + socketStream << (quint64)activeCellCount; + quint64 byteCount = doubleValueCount * sizeof(double); + socketStream << byteCount; + + // This structure is supposed to be received by Octave using a NDArray. The ordering of this loop is // defined by the ordering of the receiving NDArray // @@ -162,27 +170,25 @@ class RiaGetActiveCellCenters : public RiaSocketCommand // dv(0) = coordCount; // dv(1) = 3; - std::vector cellCenterValues(doubleValueCount); - quint64 coordCount = 0; + size_t blockByteCount = activeCellCount * sizeof(double); + std::vector doubleValues(blockByteCount); + for (int coordIdx = 0; coordIdx < 3; coordIdx++) { + quint64 valueIndex = 0; + for (size_t globalCellIdx = 0; globalCellIdx < mainGrid->cells().size(); globalCellIdx++) { if (!actCellInfo->isActive(globalCellIdx)) continue; cvf::Vec3d center = mainGrid->cells()[globalCellIdx].center(); - cellCenterValues[coordCount++] = center[coordIdx]; + doubleValues[valueIndex++] = center[coordIdx]; } - } - - CVF_ASSERT(coordCount == doubleValueCount); - socketStream << (quint64)activeCellCount; - quint64 byteCount = doubleValueCount * sizeof(double); - socketStream << byteCount; - - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCenterValues.data(), byteCount); + CVF_ASSERT(valueIndex == activeCellCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); + } return true; } @@ -244,67 +250,37 @@ class RiaGetCellCorners : public RiaSocketCommand // dv(3) = 8; // dv(4) = 3; - cvf::Timer timer; + cvf::Vec3d cornerVerts[8]; + size_t blockByteCount = cellCount * sizeof(double); + std::vector doubleValues(blockByteCount); - if (RiaApplication::instance()->preferences()->useStreamTransfer()) + for (int coordIdx = 0; coordIdx < 3; coordIdx++) { - cvf::Vec3d cornerVerts[8]; - for (int coordIdx = 0; coordIdx < 3; coordIdx++) + for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) { - for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) - { - size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; + size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; - for (size_t k = 0; k < cellCountK; k++) - { - for (size_t j = 0; j < cellCountJ; j++) - { - for (size_t i = 0; i < cellCountI; i++) - { - size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); - rigGrid->cellCornerVertices(localCellIdx, cornerVerts); + quint64 valueIndex = 0; - socketStream << cornerVerts[cornerIndexMapping][coordIdx]; - } - } - } - } - } - } - else - { - std::vector cellCornerValues(doubleValueCount); - cvf::Vec3d cornerVerts[8]; - quint64 coordCount = 0; - for (int coordIdx = 0; coordIdx < 3; coordIdx++) - { - for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) + for (size_t k = 0; k < cellCountK; k++) { - size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; - - for (size_t k = 0; k < cellCountK; k++) + for (size_t j = 0; j < cellCountJ; j++) { - for (size_t j = 0; j < cellCountJ; j++) + for (size_t i = 0; i < cellCountI; i++) { - for (size_t i = 0; i < cellCountI; i++) - { - size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); - rigGrid->cellCornerVertices(localCellIdx, cornerVerts); + size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); + rigGrid->cellCornerVertices(localCellIdx, cornerVerts); - cellCornerValues[coordCount++] = cornerVerts[cornerIndexMapping][coordIdx]; - } + doubleValues[valueIndex++] = cornerVerts[cornerIndexMapping][coordIdx]; } } } - } - - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCornerValues.data(), byteCount); - } - double totalTimeMS = timer.time() * 1000.0; - QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); + CVF_ASSERT(valueIndex, cellCount); - server->errorMessageDialog()->showMessage(resultInfo); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); + } + } return true; } @@ -348,6 +324,10 @@ class RiaGetActiveCellCorners : public RiaSocketCommand size_t activeCellCount = actCellInfo->globalActiveCellCount(); size_t doubleValueCount = activeCellCount * 3 * 8; + socketStream << (quint64)activeCellCount; + quint64 byteCount = doubleValueCount * sizeof(double); + socketStream << byteCount; + // This structure is supposed to be received by Octave using a NDArray. The ordering of this loop is // defined by the ordering of the receiving NDArray // @@ -359,31 +339,32 @@ class RiaGetActiveCellCorners : public RiaSocketCommand // dv(1) = 8; // dv(2) = 3; - std::vector cellCornerValues(doubleValueCount); cvf::Vec3d cornerVerts[8]; - quint64 coordCount = 0; + size_t blockByteCount = activeCellCount * sizeof(double); + std::vector doubleValues(blockByteCount); + for (int coordIdx = 0; coordIdx < 3; coordIdx++) { for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) { size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; + quint64 valueIndex = 0; + for (size_t globalCellIdx = 0; globalCellIdx < mainGrid->cells().size(); globalCellIdx++) { if (!actCellInfo->isActive(globalCellIdx)) continue; mainGrid->cellCornerVertices(globalCellIdx, cornerVerts); - cellCornerValues[coordCount++] = cornerVerts[cornerIndexMapping][coordIdx]; + doubleValues[valueIndex++] = cornerVerts[cornerIndexMapping][coordIdx]; } - } - } - socketStream << (quint64)activeCellCount; - quint64 byteCount = doubleValueCount * sizeof(double); - socketStream << byteCount; + CVF_ASSERT(valueIndex == activeCellCount); - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCornerValues.data(), byteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); + } + } return true; } diff --git a/OctavePlugin/riGetActiveCellCenters.cpp b/OctavePlugin/riGetActiveCellCenters.cpp index 90c1631f30..a98ba06bac 100644 --- a/OctavePlugin/riGetActiveCellCenters.cpp +++ b/OctavePlugin/riGetActiveCellCenters.cpp @@ -1,7 +1,10 @@ #include +#include + #include #include "riSettings.h" +#include "riSocketTools.h" void getActiveCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 port, const qint32& caseId, const QString& porosityModel) @@ -61,24 +64,16 @@ void getActiveCellCenters(NDArray& cellCenterValues, const QString &hostName, qu cellCenterValues.resize(dv); - while (socket.bytesAvailable() < (qint64)(byteCount)) + double* internalMatrixData = cellCenterValues.fortran_vec(); + QStringList errorMessages; + if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) + for (int i = 0; i < errorMessages.size(); i++) { - error((("Waiting for data: ") + socket.errorString()).toLatin1().data()); - return; + error(errorMessages[i].toLatin1().data()); } - OCTAVE_QUIT; - } - - quint64 bytesRead = 0; - double* internalMatrixData = cellCenterValues.fortran_vec(); - bytesRead = socket.read((char*)(internalMatrixData), byteCount); - if (byteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - octave_stdout << "Active cell count: " << activeCellCount << std::endl; + OCTAVE_QUIT; } return; diff --git a/OctavePlugin/riGetActiveCellCorners.cpp b/OctavePlugin/riGetActiveCellCorners.cpp index 6fb285cc4a..47ffad52bc 100644 --- a/OctavePlugin/riGetActiveCellCorners.cpp +++ b/OctavePlugin/riGetActiveCellCorners.cpp @@ -1,7 +1,10 @@ #include +#include + #include #include "riSettings.h" +#include "riSocketTools.h" void getActiveCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 port, const qint32& caseId, const QString& porosityModel) @@ -61,24 +64,16 @@ void getActiveCellCorners(NDArray& cellCornerValues, const QString &hostName, qu dv(2) = 3; cellCornerValues.resize(dv); - while (socket.bytesAvailable() < (qint64)(byteCount)) + double* internalMatrixData = cellCornerValues.fortran_vec(); + QStringList errorMessages; + if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) + for (int i = 0; i < errorMessages.size(); i++) { - error((("Waiting for data: ") + socket.errorString()).toLatin1().data()); - return; + error(errorMessages[i].toLatin1().data()); } - OCTAVE_QUIT; - } - - quint64 bytesRead = 0; - double* internalMatrixData = cellCornerValues.fortran_vec(); - bytesRead = socket.read((char*)(internalMatrixData), byteCount); - if (byteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - octave_stdout << "Active cell count: " << activeCellCount << std::endl; + OCTAVE_QUIT; } return; diff --git a/OctavePlugin/riGetCellCenters.cpp b/OctavePlugin/riGetCellCenters.cpp index cb65de3d01..4f57d08a2b 100644 --- a/OctavePlugin/riGetCellCenters.cpp +++ b/OctavePlugin/riGetCellCenters.cpp @@ -1,7 +1,10 @@ #include +#include + #include #include "riSettings.h" +#include "riSocketTools.h" void getCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 port, const qint32& caseId, const quint32& gridIndex) @@ -66,39 +69,19 @@ void getCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 dv(3) = 3; cellCenterValues.resize(dv); - while (socket.bytesAvailable() < (qint64)(byteCount)) - { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) - { - error((("Waiting for data: ") + socket.errorString()).toLatin1().data()); - return; - } - OCTAVE_QUIT; - } - - //octave_stdout << " riGetCellCenters : I = " << cellCountI <<" J = " << cellCountJ << " K = " << cellCountK << std::endl; - //octave_stdout << " riGetCellCenters : numDoubles = " << valueCount << std::endl; double* internalMatrixData = cellCenterValues.fortran_vec(); - -#if 0 - octave_idx_type valueCount = cellCenterValues.length(); - double val; - for (octave_idx_type i = 0; i < valueCount; i++) + QStringList errorMessages; + if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) { - socketStream >> internalMatrixData[i]; - } -#else - quint64 bytesRead = 0; - bytesRead = socket.read((char*)(internalMatrixData), byteCount); + for (int i = 0; i < errorMessages.size(); i++) + { + error(errorMessages[i].toLatin1().data()); + } - if (byteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - octave_stdout << "Cell count: " << cellCount << std::endl; + OCTAVE_QUIT; } -#endif return; } diff --git a/OctavePlugin/riGetCellCorners.cpp b/OctavePlugin/riGetCellCorners.cpp index f5e3b2c356..2571371a76 100644 --- a/OctavePlugin/riGetCellCorners.cpp +++ b/OctavePlugin/riGetCellCorners.cpp @@ -84,41 +84,6 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 OCTAVE_QUIT; } - octave_stdout << "Bytes count processed : " << byteCount << std::endl; - - - /* - while (socket.bytesAvailable() < (qint64)(byteCount)) - { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) - { - error((("Waiting for data: ") + socket.errorString()).toLatin1().data()); - return; - } - OCTAVE_QUIT; - } - - double* internalMatrixData = cellCornerValues.fortran_vec(); - -#if 0 - double val; - for (octave_idx_type i = 0; i < valueCount; i++) - { - socketStream >> internalMatrixData[i]; - } -#else - quint64 bytesRead = 0; - bytesRead = socket.read((char*)(internalMatrixData), byteCount); - - if (byteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - octave_stdout << "Cell count: " << cellCount << std::endl; - } - -#endif - */ - return; } From 9aa32e4a887e2bc271201d5b5ab8e2fc94bdff2d Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 3 Apr 2014 10:58:29 +0200 Subject: [PATCH 020/130] Added isCoarseningActive --- ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp | 8 ++++++++ ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h | 1 + 2 files changed, 9 insertions(+) diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp index bb0da770da..b58b17c5d4 100644 --- a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp @@ -193,6 +193,14 @@ void RigActiveCellInfo::clear() m_activeCellsBoundingBox.reset(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigActiveCellInfo::isCoarseningActive() const +{ + return m_globalCellResultCount != m_globalActiveCellCount; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h index 2719dbffb5..cbe11c9b8c 100644 --- a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h @@ -36,6 +36,7 @@ class RigActiveCellInfo : public cvf::Object size_t globalCellCount() const; size_t globalActiveCellCount() const; size_t globalCellResultCount() const; + bool isCoarseningActive() const; bool isActive(size_t globalCellIndex) const; size_t cellResultIndex(size_t globalCellIndex) const; From 34e6d98c767f05bb2fa25d33a757e2aecd73c800 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 3 Apr 2014 11:09:42 +0200 Subject: [PATCH 021/130] Updated use of buffer read --- OctavePlugin/riGetActiveCellInfo.cpp | 48 +++++++--------------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/OctavePlugin/riGetActiveCellInfo.cpp b/OctavePlugin/riGetActiveCellInfo.cpp index 824134e0f7..a7213a3697 100644 --- a/OctavePlugin/riGetActiveCellInfo.cpp +++ b/OctavePlugin/riGetActiveCellInfo.cpp @@ -1,7 +1,10 @@ #include +#include + #include #include "riSettings.h" +#include "riSocketTools.h" void getActiveCellInfo(int32NDArray& activeCellInfo, const QString &hostName, quint16 port, const qint64& caseId, const QString& porosityModel) @@ -43,59 +46,32 @@ void getActiveCellInfo(int32NDArray& activeCellInfo, const QString &hostName, qu // Read timestep count and blocksize quint64 columnCount; - quint64 byteCount; + quint64 byteCountForOneTimestep; size_t activeCellCount; socketStream >> columnCount; - socketStream >> byteCount; + socketStream >> byteCountForOneTimestep; - activeCellCount = byteCount / sizeof(qint32); + activeCellCount = byteCountForOneTimestep / sizeof(qint32); dim_vector dv (2, 1); dv(0) = activeCellCount; dv(1) = columnCount; activeCellInfo.resize(dv); - if (!(byteCount && columnCount)) + if (!(byteCountForOneTimestep && columnCount)) { error ("Could not find the requested data in ResInsight"); return; } - // Wait for available data for each column, then read data for each column - for (size_t tIdx = 0; tIdx < columnCount; ++tIdx) + qint32* internalMatrixData = (qint32*)activeCellInfo.fortran_vec()->mex_get_data(); + QStringList errorMessages; + if (!readBlockData(socket, (char*)(internalMatrixData), columnCount * byteCountForOneTimestep, errorMessages)) { - while (socket.bytesAvailable() < (int)byteCount) - { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) - { - QString errorMsg = QString("Waiting for column number: %1 of %2: %3").arg(tIdx).arg(columnCount).arg(socket.errorString()); - - error(errorMsg.toLatin1().data()); - octave_stdout << "Active cells: " << activeCellCount << ", Columns: " << columnCount << std::endl; - return ; - } - OCTAVE_QUIT; - } - - qint64 bytesRead = 0; - qint32* internalMatrixData = (qint32*)activeCellInfo.fortran_vec()->mex_get_data(); - -#if 1 // Use raw data transfer. Faster. - bytesRead = socket.read((char*)(internalMatrixData + tIdx * activeCellCount), byteCount); -#else - for (size_t cIdx = 0; cIdx < activeCellCount; ++cIdx) - { - socketStream >> internalMatrixData[tIdx * activeCellCount + cIdx]; - - if (socketStream.status() == QDataStream::Ok) bytesRead += sizeof(int); - } -#endif - - if ((int)byteCount != bytesRead) + for (int i = 0; i < errorMessages.size(); i++) { - error("Could not read binary double data properly from socket"); - octave_stdout << "Active cells: " << activeCellCount << ", Columns: " << columnCount << std::endl; + error(errorMessages[i].toLatin1().data()); } OCTAVE_QUIT; From 770f70680345d00c4b6c828e1e36f3f12000a390 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 3 Apr 2014 11:56:01 +0200 Subject: [PATCH 022/130] Updated riGetGridProperty --- .../RiaPropertyDataCommands.cpp | 57 +++--------- OctavePlugin/riGetGridProperty.cpp | 92 ++----------------- 2 files changed, 22 insertions(+), 127 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index 00210e4e21..87cf148f7c 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -306,60 +306,27 @@ class RiaGetGridProperty: public RiaSocketCommand quint64 timestepCount = (quint64)requestedTimesteps.size(); socketStream << timestepCount; - size_t valueIdx = 0; - cvf::Timer timer; - - if (RiaApplication::instance()->preferences()->useStreamTransfer()) + for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { - for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) + cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); + if (cellCenterDataAccessObject.isNull()) { - cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); - if (cellCenterDataAccessObject.isNull()) - { - continue; - } - - for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) - { - double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); - if (cellValue == HUGE_VAL) - { - cellValue = 0.0; - } - - socketStream << cellValue; - } + continue; } - } - else - { - for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) + std::vector values(rigGrid->cellCount()); + for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) { - cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); - if (cellCenterDataAccessObject.isNull()) - { - continue; - } - - std::vector values(rigGrid->cellCount()); - for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) + double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); + if (cellValue == HUGE_VAL) { - double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); - if (cellValue == HUGE_VAL) - { - cellValue = 0.0; - } - values[valueIdx++] = cellValue; + cellValue = 0.0; } - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), values.size() * sizeof(double)); + values[cellIdx] = cellValue; } - } - double totalTimeMS = timer.time() * 1000.0; - QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); - - server->errorMessageDialog()->showMessage(resultInfo); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), values.size() * sizeof(double)); + } return true; } diff --git a/OctavePlugin/riGetGridProperty.cpp b/OctavePlugin/riGetGridProperty.cpp index 3b1fbc589f..e477cd767a 100644 --- a/OctavePlugin/riGetGridProperty.cpp +++ b/OctavePlugin/riGetGridProperty.cpp @@ -1,6 +1,11 @@ #include +#include + #include + #include "riSettings.h" +#include "riSocketTools.h" + void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 serverPort, const int& caseId, int gridIdx, QString propertyName, const int32NDArray& requestedTimeSteps, QString porosityModel) @@ -61,8 +66,6 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 totalByteCount = cellCountI*cellCountJ*cellCountK*timestepCount*sizeof(double); - qint64 timestepByteCount = cellCountI*cellCountJ*cellCountK*sizeof(double); - if (!(totalByteCount)) { error ("Could not find the requested data in ResInsight"); @@ -78,93 +81,18 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 propertyFrames.resize(dv); - -#if 1 - // Wait for available data for each timestep, then read data for each timestep - - qint64 totalBytesRead = 0; - - for (size_t tIdx = 0; tIdx < timestepCount; ++tIdx) + double* internalMatrixData = propertyFrames.fortran_vec(); + QStringList errorMessages; + if (!readBlockData(socket, (char*)(internalMatrixData), totalByteCount, errorMessages)) { - qint64 bytesAvailable = socket.bytesAvailable() ; - - while ( bytesAvailable < (qint64)timestepByteCount) + for (int i = 0; i < errorMessages.size(); i++) { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) - { - error((("Waiting for timestep data number: ") + QString::number(tIdx)+ ": " + socket.errorString()).toLatin1().data()); - octave_stdout << "Cellcount: " << cellCountI*cellCountJ*cellCountK << ", Timesteps: " << timestepCount << std::endl; - return ; - } - - bytesAvailable = socket.bytesAvailable(); - - OCTAVE_QUIT; + error(errorMessages[i].toLatin1().data()); } - qint64 bytesRead = 0; - double * internalMatrixData = propertyFrames.fortran_vec(); - - // Raw data transfer. Faster. Not possible when dealing with coarsening - bytesRead = socket.read(((char*)(internalMatrixData)) + tIdx * timestepByteCount, timestepByteCount); - - if ((qint64)timestepByteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - octave_stdout << "Cellcount: " << cellCountI*cellCountJ*cellCountK << ", Timesteps count: " << timestepCount << std::endl; - octave_stdout << "Timestep : " << tIdx << std::endl; - } - - totalBytesRead += bytesRead; - - OCTAVE_QUIT; - } - - if ((qint64)totalByteCount != totalBytesRead) - { - error("Could not read binary double data properly from socket"); - } - - #else - - // Wait for available data - qint64 bytesAvailable = socket.bytesAvailable() ; - - while (bytesAvailable < (qint64)totalByteCount) - { - octave_stdout << "Waiting for data. Has : " << bytesAvailable << " Needs :" << totalByteCount << std::endl; - if (!socket.waitForReadyRead(riOctavePlugin::shortTimeOutMilliSecs)) - { - //error(("Waiting for data : " + socket.errorString()).toLatin1().data()); - //return ; - } - - bytesAvailable = socket.bytesAvailable() ; OCTAVE_QUIT; } - qint64 bytesRead = 0; - double * internalMatrixData = propertyFrames.fortran_vec(); - -#if 0 - - char* dataBuffer = new char[totalByteCount]; - bytesRead = socket.read(dataBuffer, totalByteCount); - - -#else - - // Raw data transfer. Faster. - bytesRead = socket.read((char*)(internalMatrixData ), totalByteCount); -#endif - - - if ((qint64)totalByteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - } - -#endif QString tmp = QString("riGetGridProperty : Read %1").arg(propertyName); if (caseId < 0) From 486f383de7dac90979b46ab50da536d204ff7abd Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 11 Apr 2014 11:06:42 +0200 Subject: [PATCH 023/130] Integrated changes for framework Pdm fields can contain a forward declared Pdm object without the include file VizFwk: Added VertexColoring shader to be able to use per vertex color used from drawableGeo::setColorArray() --- Fwk/AppFwk/cafProjectDataModel/CMakeLists.txt | 3 +- Fwk/AppFwk/cafProjectDataModel/cafPdmField.h | 2 +- .../cafProjectDataModel/cafPdmField.inl | 50 +- .../cafProjectDataModel/cafPdmObject.cpp | 14 +- Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h | 2 +- .../cafPdmUiObjectEditorHandle.cpp | 2 + .../cafPdmUiObjectEditorHandle.h | 1 + .../cafPdmUiTreeEditorHandle.cpp | 76 +++ .../cafPdmUiTreeEditorHandle.h | 78 +++ .../cafPdmUiTreeOrdering.cpp | 26 +- .../cafPdmUiTreeOrdering.h | 18 +- .../CMakeLists.txt | 3 + .../cafProjectDataModel_UnitTests/Child.cpp | 13 + .../cafProjectDataModel_UnitTests/Child.h | 22 + .../cafProjectDataModel_UnitTests/Parent.cpp | 32 + .../cafProjectDataModel_UnitTests/Parent.h | 52 ++ .../cafProjectDataModel_UnitTests/TestObj.cpp | 11 + .../cafProjectDataModel_UnitTests/TestObj.h | 18 + Fwk/AppFwk/cafUserInterface/CMakeLists.txt | 3 + .../cafPdmUiTreeViewModel.cpp | 567 ++++++++++++++++++ .../cafUserInterface/cafPdmUiTreeViewModel.h | 114 ++++ .../Utils/ceeDetermineCompilerFlags.cmake | 6 +- Fwk/VizFwk/CMakeLists.txt | 7 + Fwk/VizFwk/LibCore/CMakeLists.txt | 3 +- Fwk/VizFwk/LibCore/LibCore.vcxproj | 2 + Fwk/VizFwk/LibCore/LibCore.vcxproj.filters | 4 +- Fwk/VizFwk/LibCore/cvfArrayWrapperConst.h | 1 + Fwk/VizFwk/LibCore/cvfArrayWrapperToEdit.h | 1 + Fwk/VizFwk/LibCore/cvfAssert.cpp | 8 +- Fwk/VizFwk/LibCore/cvfAtomicCounter.cpp | 193 ++++++ Fwk/VizFwk/LibCore/cvfAtomicCounter.h | 96 +++ Fwk/VizFwk/LibCore/cvfBase.h | 19 +- Fwk/VizFwk/LibCore/cvfObject.h | 15 + Fwk/VizFwk/LibCore/cvfObject.inl | 4 +- Fwk/VizFwk/LibCore/cvfPlane.cpp | 125 +++- Fwk/VizFwk/LibCore/cvfPlane.h | 3 +- Fwk/VizFwk/LibCore/cvfVector2.h | 2 + Fwk/VizFwk/LibCore/cvfVector2.inl | 21 + Fwk/VizFwk/LibGeometry/CMakeLists.txt | 2 + Fwk/VizFwk/LibGeometry/LibGeometry.vcxproj | 2 + .../LibGeometry/LibGeometry.vcxproj.filters | 2 + Fwk/VizFwk/LibGeometry/cvfPrimitiveTests.cpp | 106 ++++ Fwk/VizFwk/LibGeometry/cvfPrimitiveTests.h | 56 ++ Fwk/VizFwk/LibGuiQt/cvfqtMouseState.h | 3 +- Fwk/VizFwk/LibRender/LibRender.vcxproj | 7 +- .../LibRender/LibRender.vcxproj.filters | 9 +- .../LibRender/cvfShaderSourceRepository.cpp | 2 + .../LibRender/cvfShaderSourceRepository.h | 1 + Fwk/VizFwk/LibRender/cvfShaderSourceStrings.h | 21 + .../glsl/src_VaryingColorGlobalAlpha.glsl | 12 + Fwk/VizFwk/LibRender/glsl/vs_Standard.glsl | 3 + Fwk/VizFwk/LibUtilities/cvfuImageTga.cpp | 7 +- Fwk/VizFwk/LibUtilities/cvfuImageTga.h | 2 +- Fwk/VizFwk/LibViewing/cvfModelBasicList.cpp | 10 + Fwk/VizFwk/LibViewing/cvfModelBasicList.h | 1 + .../Tests/LibCore_UnitTests/CMakeLists.txt | 1 + .../LibCore_UnitTests.vcxproj | 1 + .../LibCore_UnitTests.vcxproj.filters | 3 +- .../cvfArrayWrapper-Test.cpp | 5 +- .../cvfAtomicCounter-Test.cpp | 141 +++++ .../LibCore_UnitTests/cvfVector2-Test.cpp | 32 + .../LibGeometry_UnitTests/CMakeLists.txt | 1 + .../LibGeometry_UnitTests.vcxproj | 1 + .../LibGeometry_UnitTests.vcxproj.filters | 1 + .../cvfPrimitiveTests-Test.cpp | 90 +++ .../cvfModelBasicList-Test.cpp | 45 ++ .../SnippetsBasis/snipVertexColoring.cpp | 75 ++- .../Tests/SnippetsBasis/snipVertexColoring.h | 6 +- 68 files changed, 2177 insertions(+), 88 deletions(-) create mode 100644 Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.cpp create mode 100644 Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.h create mode 100644 Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.cpp create mode 100644 Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.h create mode 100644 Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.cpp create mode 100644 Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.h create mode 100644 Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/TestObj.cpp create mode 100644 Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/TestObj.h create mode 100644 Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp create mode 100644 Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h create mode 100644 Fwk/VizFwk/LibCore/cvfAtomicCounter.cpp create mode 100644 Fwk/VizFwk/LibCore/cvfAtomicCounter.h create mode 100644 Fwk/VizFwk/LibGeometry/cvfPrimitiveTests.cpp create mode 100644 Fwk/VizFwk/LibGeometry/cvfPrimitiveTests.h create mode 100644 Fwk/VizFwk/LibRender/glsl/src_VaryingColorGlobalAlpha.glsl create mode 100644 Fwk/VizFwk/Tests/LibCore_UnitTests/cvfAtomicCounter-Test.cpp create mode 100644 Fwk/VizFwk/Tests/LibGeometry_UnitTests/cvfPrimitiveTests-Test.cpp diff --git a/Fwk/AppFwk/cafProjectDataModel/CMakeLists.txt b/Fwk/AppFwk/cafProjectDataModel/CMakeLists.txt index 06cfc5c95e..24bc987236 100644 --- a/Fwk/AppFwk/cafProjectDataModel/CMakeLists.txt +++ b/Fwk/AppFwk/cafProjectDataModel/CMakeLists.txt @@ -31,5 +31,6 @@ add_library( ${PROJECT_NAME} cafPdmUiOrdering.h cafPdmUiTreeOrdering.cpp cafPdmUiTreeOrdering.h - + cafPdmUiTreeEditorHandle.h + cafPdmUiTreeEditorHandle.cpp ) diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmField.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmField.h index d718abc681..d8066b7ad9 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmField.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmField.h @@ -171,7 +171,7 @@ class PdmField : public PdmFieldHandle { typedef DataType* DataTypePtr; public: - PdmField() : PdmFieldHandle() { m_fieldValue = NULL; } + PdmField() : PdmFieldHandle() { } PdmField(const PdmField& other); PdmField(const DataTypePtr& fieldValue); virtual ~PdmField(); diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmField.inl b/Fwk/AppFwk/cafProjectDataModel/cafPdmField.inl index 4d4e581a54..5d60952b13 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmField.inl +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmField.inl @@ -292,7 +292,7 @@ void caf::PdmField::readFieldData(QXmlStreamReader& xmlStream) } else { - if (dynamic_cast(obj) == NULL) + if (obj->classKeyword() != className) { assert(false); // Inconsistency in the factory. It creates objects of wrong type from the ClassKeyword @@ -341,7 +341,7 @@ void caf::PdmField::readFieldData(QXmlStreamReader& xmlStream) template void caf::PdmField::writeFieldData(QXmlStreamWriter& xmlStream) { - if (m_fieldValue == NULL) return; + if (m_fieldValue.rawPtr() == NULL) return; QString className = m_fieldValue.rawPtr()->classKeyword(); @@ -397,7 +397,7 @@ template caf::PdmField::~PdmField() { if (!m_fieldValue.isNull()) m_fieldValue.rawPtr()->removeParentField(this); - m_fieldValue = NULL; + m_fieldValue.setRawPtr(NULL); } //-------------------------------------------------------------------------------------------------- @@ -553,7 +553,6 @@ size_t PdmPointersField::count(const DataType* pointer) const template void PdmPointersField::clear() { - this->removeThisAsParentField(); m_pointers.clear(); } @@ -567,7 +566,7 @@ void PdmPointersField::deleteAllChildObjects() size_t index; for (index = 0; index < m_pointers.size(); ++index) { - delete(m_pointers[index]); + delete(m_pointers[index].rawPtr()); } m_pointers.clear(); @@ -579,7 +578,11 @@ void PdmPointersField::deleteAllChildObjects() template void PdmPointersField::erase(size_t index) { - if (m_pointers[index]) m_pointers[index]->removeParentField(this); + if (m_pointers[index]) + { + m_pointers[index]->removeParentField(this); + } + m_pointers.erase(m_pointers.begin() + index); } @@ -589,21 +592,23 @@ void PdmPointersField::erase(size_t index) template void PdmPointersField::removeChildObject(PdmObject* object) { - DataType* pointer = dynamic_cast(object); - - size_t index; std::vector< PdmPointer > tempPointers; + tempPointers = m_pointers; m_pointers.clear(); - for (index = 0; index < tempPointers.size(); ++index) + + for (size_t index = 0; index < tempPointers.size(); ++index) { - if (tempPointers[index] != pointer) + if (tempPointers[index].rawPtr() != object) { m_pointers.push_back(tempPointers[index]); } else { - if (tempPointers[index]) tempPointers[index]->removeParentField(this); + if (tempPointers[index].rawPtr()) + { + tempPointers[index].rawPtr()->removeParentField(this); + } } } } @@ -618,12 +623,12 @@ template typename std::vector< PdmPointer >::iterator it; for (it = m_pointers.begin(); it != m_pointers.end(); ++it) { - if (*it == NULL) continue; + if (it->rawPtr() == NULL) continue; - QString className = (*it)->classKeyword(); + QString className = it->rawPtr()->classKeyword(); xmlStream.writeStartElement("", className); - (*it)->writeFields(xmlStream); + it->rawPtr()->writeFields(xmlStream); xmlStream.writeEndElement(); } } @@ -661,9 +666,7 @@ template continue; } - currentObject = dynamic_cast (obj); - - if (currentObject == NULL) + if (obj->classKeyword() != className) { assert(false); // There is an inconsistency in the factory. It creates objects of type not matching the ClassKeyword @@ -678,8 +681,11 @@ template continue; } - currentObject->readFields(xmlStream); - this->push_back(currentObject); + obj->readFields(xmlStream); + + m_pointers.push_back(PdmPointer()); + m_pointers.back().setRawPtr(obj); + obj->addParentField(this); // Jump off the end element, and head for next start element (or the final EndElement of the field) // Qt reports a character token between EndElements and StartElements so skip it @@ -700,7 +706,7 @@ void PdmPointersField::childObjects(std::vector* objects) size_t i; for (i = 0; i < m_pointers.size(); ++i) { - objects->push_back(m_pointers[i]); + objects->push_back(m_pointers[i].rawPtr()); } } @@ -715,7 +721,7 @@ void PdmPointersField::removeThisAsParentField() { if (!it->isNull()) { - (*it)->removeParentField(this); + it->rawPtr()->removeParentField(this); } } } diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.cpp index 9f6acd1a49..d752765d8e 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.cpp @@ -421,7 +421,7 @@ PdmUiTreeOrdering* PdmObject::uiTreeOrdering(QString uiConfigName /*= ""*/) } } - expandUiTree(uiTreeOrdering, uiConfigName); + addUiTreeChildren(uiTreeOrdering, uiConfigName); return uiTreeOrdering; } @@ -429,13 +429,13 @@ PdmUiTreeOrdering* PdmObject::uiTreeOrdering(QString uiConfigName /*= ""*/) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmObject::expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName /*= "" */) +void PdmObject::addUiTreeChildren(PdmUiTreeOrdering* root, QString uiConfigName /*= "" */) { if (!root) return; - if ( root->childCount() == 0) + if ( root->childCount() == 0) // This means that no one has tried to expand it. { - if (!root->isSubTreeDefined() && root->dataObject()) + if (!root->ignoreSubTree() && root->dataObject()) { if (root->m_field && !root->m_field->isUiChildrenHidden(uiConfigName)) @@ -449,7 +449,7 @@ void PdmObject::expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName /*= " } else { - root->dataObject()->defineUiTreeOrdering(*root, uiConfigName); + root->object()->defineUiTreeOrdering(*root, uiConfigName); } } } @@ -457,9 +457,9 @@ void PdmObject::expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName /*= " for (int cIdx = 0; cIdx < root->childCount(); ++cIdx) { PdmUiTreeOrdering* child = dynamic_cast(root->child(cIdx)); - if (!child->isSubTreeDefined()) + if (!child->ignoreSubTree()) { - expandUiTree(child); + addUiTreeChildren(child); } } } diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h index 75fd509b53..94eb759c48 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h @@ -255,7 +255,7 @@ class PdmObject : public PdmUiItem private: /// Recursive function to traverse and create a Ui tree representation of the object hierarchy - static void expandUiTree( PdmUiTreeOrdering* root, QString uiConfigName = "" ); + static void addUiTreeChildren( PdmUiTreeOrdering* root, QString uiConfigName = "" ); private: std::multiset m_parentFields; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiObjectEditorHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiObjectEditorHandle.cpp index f5b845ab81..be166acb83 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiObjectEditorHandle.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiObjectEditorHandle.cpp @@ -59,6 +59,8 @@ QWidget* PdmUiObjectEditorHandle::getOrCreateWidget(QWidget* parent) //-------------------------------------------------------------------------------------------------- void PdmUiObjectEditorHandle::setPdmObject(PdmObject* object) { + cleanupBeforeSettingPdmObject(); + this->bindToPdmItem(object); } diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiObjectEditorHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiObjectEditorHandle.h index 45138b2f35..f7bcb41bfd 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiObjectEditorHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiObjectEditorHandle.h @@ -66,6 +66,7 @@ class PdmUiObjectEditorHandle: public PdmUiEditorHandle protected: virtual QWidget* createWidget(QWidget* parent) = 0; + virtual void cleanupBeforeSettingPdmObject() {}; protected: QPointer m_widget; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.cpp new file mode 100644 index 0000000000..943a9a0fbe --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.cpp @@ -0,0 +1,76 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmUiTreeEditorHandle.h" +#include "cafPdmObject.h" + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* PdmUiTreeEditorHandle::getOrCreateWidget(QWidget* parent) +{ + if (m_widget.isNull()) + { + m_widget = this->createWidget(parent); + } + return m_widget; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeEditorHandle::setPdmItemRoot(PdmUiItem* root) +{ + cleanupBeforeSettingPdmObject(); + + this->bindToPdmItem(root); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiItem* PdmUiTreeEditorHandle::pdmItemRoot() +{ + return this->pdmItem(); +} + +} //End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.h new file mode 100644 index 0000000000..e96a59c6b9 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.h @@ -0,0 +1,78 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once +#include +#include +#include +#include +#include "cafPdmUiEditorHandle.h" +#include "cafPdmPointer.h" + +namespace caf +{ + +class PdmObject; + +//================================================================================================== +/// Abstract class to handle editors for complete PdmObjects +//================================================================================================== + +class PdmUiTreeEditorHandle: public PdmUiEditorHandle +{ +public: + PdmUiTreeEditorHandle() {} + ~PdmUiTreeEditorHandle() {} + + QWidget* getOrCreateWidget(QWidget* parent); + QWidget* widget() { return m_widget; } + + void setPdmItemRoot(PdmUiItem* root); + PdmUiItem* pdmItemRoot(); + +protected: + virtual QWidget* createWidget(QWidget* parent) = 0; + virtual void cleanupBeforeSettingPdmObject() {}; + +protected: + QPointer m_widget; +}; + + + +} // End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeOrdering.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeOrdering.cpp index 9135a6c07d..bea9b8a19a 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeOrdering.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeOrdering.cpp @@ -65,7 +65,11 @@ namespace caf PdmUiTreeOrdering* PdmUiTreeOrdering::add(const QString & title, const QString& iconResourceName) { PdmUiTreeOrdering* to = new PdmUiTreeOrdering(this, -1, NULL); - to->m_uiInfo = new PdmUiItemInfo(title, QIcon(iconResourceName)); + + to->m_uiItem = new PdmUiItem(); + to->m_uiItem->setUiName(title); + to->m_uiItem->setUiIcon(QIcon(iconResourceName)); + return to; } @@ -98,7 +102,7 @@ namespace caf { PdmUiTreeOrdering* child = dynamic_cast(this->child(cIdx)); - if (child->dataObject() == object) + if (child->object() == object) { return true; } @@ -112,15 +116,27 @@ namespace caf /// Creates an new PdmUiTreeOrdering item, and adds it to parent. If position is -1, it is added /// at the end of parents existing child list. //-------------------------------------------------------------------------------------------------- - PdmUiTreeOrdering::PdmUiTreeOrdering(PdmUiTreeOrdering* parent /*= NULL*/, int position /*= -1*/, PdmObject* dataObject /*= NULL*/) : UiTreeItem< PdmPointer >(parent, position, dataObject), + PdmUiTreeOrdering::PdmUiTreeOrdering(PdmUiTreeOrdering* parent /*= NULL*/, int position /*= -1*/, PdmObject* dataObject /*= NULL*/) : PdmUiTreeItem(parent, position, this), m_field(NULL), - m_uiInfo(NULL), m_forgetRemainingFields(false), - m_isSubTreeDefined(false) + m_isToIgnoreSubTree(false), + m_uiItem(NULL), + m_object(dataObject) { } + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + PdmUiTreeOrdering::~PdmUiTreeOrdering() + { + if (m_uiItem) + { + delete m_uiItem; + } + } + } //End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeOrdering.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeOrdering.h index 5d9def89b4..e43b74191d 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeOrdering.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeOrdering.h @@ -49,16 +49,19 @@ namespace caf class PdmObject; class PdmFieldHandle; -//typedef UiTreeItem > PdmUiTreeItem; +class PdmUiTreeOrdering; + +typedef UiTreeItem PdmUiTreeItem; //================================================================================================== /// Class storing a tree structure representation of some PdmObject hierarchy to be used for tree views in the Gui //================================================================================================== -class PdmUiTreeOrdering : public UiTreeItem< PdmPointer > +class PdmUiTreeOrdering : public UiTreeItem< PdmUiTreeOrdering* > { public: PdmUiTreeOrdering(PdmUiTreeOrdering* parent = NULL, int position = -1, PdmObject* dataObject = NULL); + ~PdmUiTreeOrdering(); void add(PdmFieldHandle * field); void add(PdmObject* object); @@ -67,23 +70,26 @@ class PdmUiTreeOrdering : public UiTreeItem< PdmPointer > /// If the rest of the fields containing children is supposed to be omitted, setForgetRemainingFileds to true. void setForgetRemainingFields(bool val) { m_forgetRemainingFields = val; } /// To stop the tree generation at this level, setSubTreeDefined to true - void setSubTreeDefined(bool isSubTreeDefined ) { m_isSubTreeDefined = isSubTreeDefined; } + void setIgnoreSubTree(bool doIgnoreSubTree ) { m_isToIgnoreSubTree = doIgnoreSubTree; } + PdmObject* object() const { return m_object; } PdmFieldHandle* field() const { return m_field; } + PdmUiItem* uiItem() const { return m_uiItem; } private: friend class PdmObject; bool forgetRemainingFields() const { return m_forgetRemainingFields; } - bool isSubTreeDefined() const { return m_isSubTreeDefined; } + bool ignoreSubTree() const { return m_isToIgnoreSubTree; } bool containsField(const PdmFieldHandle* field); bool containsObject(const PdmObject* object); private: + PdmPointer m_object; PdmFieldHandle* m_field; - PdmUiItemInfo* m_uiInfo; + PdmUiItem* m_uiItem; bool m_forgetRemainingFields; - bool m_isSubTreeDefined; + bool m_isToIgnoreSubTree; }; diff --git a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/CMakeLists.txt b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/CMakeLists.txt index 2835458d37..2f531891ab 100644 --- a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/CMakeLists.txt +++ b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/CMakeLists.txt @@ -14,6 +14,9 @@ include_directories ( add_executable (${PROJECT_NAME} cafPdmBasicTest.cpp cafProjectDataModel_UnitTests.cpp + Child.cpp + Parent.cpp + TestObj.cpp ${CMAKE_SOURCE_DIR}/cafTests/gtest/gtest-all.cpp ) diff --git a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.cpp b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.cpp new file mode 100644 index 0000000000..74adee05b3 --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.cpp @@ -0,0 +1,13 @@ +#include "Child.h" +#include "TestObj.h" + +CAF_PDM_SOURCE_INIT(Child, "Child"); + +Child::Child() +{ + CAF_PDM_InitFieldNoDefault(&m_testObj, "Numbers", "Important Numbers", "", "", ""); +} + +Child::~Child() +{ +} diff --git a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.h b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.h new file mode 100644 index 0000000000..82e91dfd4f --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.h @@ -0,0 +1,22 @@ +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPointer.h" + +class TestObj; + +class Child: public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + Child(); + + ~Child(); + + + caf::PdmField m_testObj; +}; + + diff --git a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.cpp b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.cpp new file mode 100644 index 0000000000..26d3f4fd01 --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.cpp @@ -0,0 +1,32 @@ +#include "Parent.h" +//#include "Child.h" + +CAF_PDM_SOURCE_INIT(Parent, "Parent"); + + +Parent::Parent() +{ + CAF_PDM_InitFieldNoDefault(&m_simpleObjectsField, "SimpleObjects", "A child object", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_simpleObjectF, "SimpleObject", "A child object", "", "", ""); +} + +Parent::~Parent() +{ +} + + void Parent::doSome() +{ + size_t i = m_simpleObjectsField.size(); + if (i){ + //Child* c = m_simpleObjectsField[0]; + //TestObj* to = c->m_testObj(); + } +} + +#include + + TEST(IncludeTest, Basic) + { + Parent* p = new Parent; + delete(p); + } diff --git a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.h b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.h new file mode 100644 index 0000000000..bb4ec86f43 --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.h @@ -0,0 +1,52 @@ +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPointer.h" + +#if 0 +class PdmPointerTarget +{ +public: + PdmPointerTarget() {} + PdmPointerTarget(const PdmPointerTarget& ) {} + PdmPointerTarget& operator=(const PdmPointerTarget& ) {} + + virtual ~PdmPointerTarget() + { + // Set all guarded pointers pointing to this to NULL + + std::set::iterator it; + for (it = m_pointersReferencingMe.begin(); it != m_pointersReferencingMe.end() ; ++it) + { + (**it) = NULL; + } + } + +private: + + // Support system for PdmPointer + + friend class PdmPointerImpl; + std::set m_pointersReferencingMe; +}; + +#endif + +class Child; + + +class Parent: public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + + +public: + Parent(); + ~Parent(); + + void doSome(); + + caf::PdmPointersField m_simpleObjectsField; + caf::PdmField m_simpleObjectF; +}; diff --git a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/TestObj.cpp b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/TestObj.cpp new file mode 100644 index 0000000000..ec07283fb7 --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/TestObj.cpp @@ -0,0 +1,11 @@ +#include "TestObj.h" + +CAF_PDM_SOURCE_INIT(TestObj, "TestObj"); + +TestObj::TestObj() +{ + CAF_PDM_InitObject("TestObj", "", "", ""); + CAF_PDM_InitField(&m_position, "Position", 8765.2, "Position", "", "", ""); +} + +TestObj::~TestObj() {} diff --git a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/TestObj.h b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/TestObj.h new file mode 100644 index 0000000000..b5a33112ea --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/TestObj.h @@ -0,0 +1,18 @@ +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPointer.h" + +class TestObj: public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + + +public: + TestObj(); + + ~TestObj(); + + caf::PdmField m_position; +}; diff --git a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt index 9db951500d..69496b3ffe 100644 --- a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt +++ b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt @@ -25,6 +25,7 @@ set( QOBJECT_HEADERS cafPdmUiPropertyView.h cafPdmUiTreeView.h + cafPdmUiTreeViewModel.h cafPdmUiListView.h cafPdmUiListViewEditor.h ) @@ -66,6 +67,8 @@ add_library( ${PROJECT_NAME} cafPdmUiTextEditor.h cafPdmUiTreeViewEditor.cpp cafPdmUiTreeViewEditor.h + cafPdmUiTreeViewModel.cpp + cafPdmUiTreeViewModel.h cafPdmUiTreeView.cpp cafProgressInfo.cpp cafProgressInfo.h diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp new file mode 100644 index 0000000000..223c98d105 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp @@ -0,0 +1,567 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmUiTreeViewModel.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmUiTreeOrdering.h" + + + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTreeViewModel::PdmUiTreeViewModel(QObject* parent) +{ + m_treeItemRoot = NULL; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewModel::setTreeItemRoot(PdmUiTreeItem* root) +{ + beginResetModel(); + + if (m_treeItemRoot) + { + delete m_treeItemRoot; + } + + m_treeItemRoot = root; + endResetModel(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QModelIndex PdmUiTreeViewModel::index(int row, int column, const QModelIndex &parentIndex /*= QModelIndex( ) */) const +{ +// if (!m_treeItemRoot) +// return QModelIndex(); + + if (!hasIndex(row, column, parentIndex)) + return QModelIndex(); + + PdmUiTreeItem* parentItem = NULL; + + if (!parentIndex.isValid()) + parentItem = m_treeItemRoot; + else + parentItem = static_cast(parentIndex.internalPointer()); + + PdmUiTreeItem* childItem = parentItem->child(row); + if (childItem) + return createIndex(row, column, childItem); + else + return QModelIndex(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QModelIndex PdmUiTreeViewModel::parent(const QModelIndex &childIndex) const +{ +// if (!m_treeItemRoot) return QModelIndex(); + + if (!childIndex.isValid()) return QModelIndex(); + + PdmUiTreeItem* childItem = static_cast(childIndex.internalPointer()); + if (!childItem) return QModelIndex(); + + PdmUiTreeItem* parentItem = childItem->parent(); + if (!parentItem) return QModelIndex(); + + if (parentItem == m_treeItemRoot) return QModelIndex(); + + return createIndex(parentItem->row(), 0, parentItem); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int PdmUiTreeViewModel::rowCount(const QModelIndex &parentIndex /*= QModelIndex( ) */) const +{ + if (!m_treeItemRoot) + return 0; + + if (parentIndex.column() > 0) + return 0; + + PdmUiTreeItem* parentItem; + if (!parentIndex.isValid()) + parentItem = m_treeItemRoot; + else + parentItem = PdmUiTreeViewModel::getTreeItemFromIndex(parentIndex); + + return parentItem->childCount(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int PdmUiTreeViewModel::columnCount(const QModelIndex &parentIndex /*= QModelIndex( ) */) const +{ + if (!m_treeItemRoot) + return 0; + + if (parentIndex.isValid()) + { + PdmUiTreeItem* parentItem = PdmUiTreeViewModel::getTreeItemFromIndex(parentIndex); + if (parentItem) + { + return parentItem->columnCount(); + } + else + { + return 0; + } + } + else + return m_treeItemRoot->columnCount(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QVariant PdmUiTreeViewModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole */) const +{ + if (!index.isValid()) + return QVariant(); + + PdmUiTreeOrdering* uitreeOrdering = static_cast(index.internalPointer()); + if (!uitreeOrdering) + { + return QVariant(); + } + PdmFieldHandle* pdmField = uitreeOrdering->field(); + PdmObject* pdmObj = uitreeOrdering->object(); + + if (role == Qt::DisplayRole || role == Qt::EditRole) + { + if (pdmField && !pdmField->uiName().isEmpty()) + { + return pdmField->uiName(); + } + else if (pdmObj) + { + if (pdmObj->userDescriptionField()) + return pdmObj->userDescriptionField()->uiValue(); + else + return pdmObj->uiName(); + } + else if (uitreeOrdering->uiItem()) + { + return uitreeOrdering->uiItem()->uiName(); + } + else + { + // Should not get here + assert(0); + } + } + else if (role == Qt::DecorationRole) + { + if (pdmField && !pdmField->uiIcon().isNull()) + { + return pdmField->uiIcon(); + } + else if (pdmObj) + { + return pdmObj->uiIcon(); + } + else if (uitreeOrdering->uiItem()) + { + return uitreeOrdering->uiItem()->uiIcon(); + } + else + { + // Should not get here + assert(0); + } + } + else if (role == Qt::ToolTipRole) + { + if (pdmField && !pdmField->uiToolTip().isEmpty()) + return pdmField->uiToolTip(); + else if (pdmObj) + { + return pdmObj->uiToolTip(); + } + else if (uitreeOrdering->uiItem()) + { + return uitreeOrdering->uiItem()->uiToolTip(); + } + else + { + // Should not get here + assert(0); + } + } + else if (role == Qt::WhatsThisRole) + { + if (pdmField && !pdmField->uiWhatsThis().isEmpty()) + return pdmField->uiWhatsThis(); + else if (pdmObj) + { + return pdmObj->uiWhatsThis(); + } + else if (uitreeOrdering->uiItem()) + { + return uitreeOrdering->uiItem()->uiWhatsThis(); + } + else + { + // Should not get here + assert(0); + } + } + else if (role == Qt::CheckStateRole) + { + if (pdmObj && pdmObj->objectToggleField()) + { + bool isToggledOn = pdmObj->objectToggleField()->uiValue().toBool(); + if (isToggledOn) + { + return Qt::Checked; + } + else + { + return Qt::Unchecked; + } + } + } + + return QVariant(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewModel::emitDataChanged(const QModelIndex& index) +{ + emit dataChanged(index, index); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiTreeViewModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/) +{ + if (!index.isValid()) + { + return false; + } + + PdmUiTreeItem* treeItem = PdmUiTreeViewModel::getTreeItemFromIndex(index); + assert(treeItem); + + PdmObject* obj = treeItem->dataObject()->object(); + if (!obj) + { + return false; + } + + if (role == Qt::EditRole && obj->userDescriptionField()) + { + obj->userDescriptionField()->setValueFromUi(value); + + emitDataChanged(index); + + return true; + } + else if (role == Qt::CheckStateRole && obj->objectToggleField()) + { + bool toggleOn = (value == Qt::Checked); + + obj->objectToggleField()->setValueFromUi(toggleOn); + + emitDataChanged(index); + + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// Enable edit of this item if we have a editable user description field for a pdmObject +/// Disable edit for other items +//-------------------------------------------------------------------------------------------------- +Qt::ItemFlags PdmUiTreeViewModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::ItemIsEnabled; + + Qt::ItemFlags flagMask = QAbstractItemModel::flags(index); + + PdmUiTreeItem* treeItem = getTreeItemFromIndex(index); + if (treeItem) + { + PdmObject* pdmObject = treeItem->dataObject()->object(); + if (pdmObject) + { + if (pdmObject->userDescriptionField() && !pdmObject->userDescriptionField()->isUiReadOnly()) + { + flagMask = flagMask | Qt::ItemIsEditable; + } + + if (pdmObject->objectToggleField()) + { + flagMask = flagMask | Qt::ItemIsUserCheckable; + } + + if (pdmObject->isUiReadOnly()) + { + flagMask = flagMask & (~Qt::ItemIsEnabled); + } + + } + } + else + { + flagMask = flagMask & (~Qt::ItemIsEditable); + } + + return flagMask; +} + + +//-------------------------------------------------------------------------------------------------- +/// Refreshes the UI-tree below the supplied root PdmObject +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewModel::updateUiSubTree(PdmObject* pdmRoot) +{ + // Build the new "Correct" Tree + + PdmUiTreeOrdering* tempUpdatedPdmTree = pdmRoot->uiTreeOrdering(); + + // Find the corresponding entry for "root" in the existing Ui tree + + QModelIndex uiSubTreeRootModelIdx = getModelIndexFromPdmObject(pdmRoot); + + PdmUiTreeItem* uiModelSubTreeRoot = NULL; + if (uiSubTreeRootModelIdx.isValid()) + { + uiModelSubTreeRoot = getTreeItemFromIndex(uiSubTreeRootModelIdx); + } + else + { + uiModelSubTreeRoot = m_treeItemRoot; + } + + + updateModelSubTree(uiSubTreeRootModelIdx, uiModelSubTreeRoot, tempUpdatedPdmTree); + + delete tempUpdatedPdmTree; +} + +//-------------------------------------------------------------------------------------------------- +/// Makes the destinationSubTreeRoot tree become identical to the tree in sourceSubTreeRoot, +/// calling begin..() end..() to make the UI update accordingly. +/// This assumes that all the items have a pointer an unique PdmObject +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewModel::updateModelSubTree(const QModelIndex& modelIdxOfDestinationSubTreeRoot, PdmUiTreeItem* destinationSubTreeRoot, PdmUiTreeItem* sourceSubTreeRoot) +{ + // First loop over children in the old ui tree, deleting the ones not present in + // the newUiTree + + for (int resultChildIdx = 0; resultChildIdx < destinationSubTreeRoot->childCount() ; ++resultChildIdx) + { + PdmUiTreeItem* oldChild = destinationSubTreeRoot->child(resultChildIdx); + int childIndex = sourceSubTreeRoot->findChildItemIndex(oldChild->dataObject()); + + if (childIndex == -1) // Not found + { + this->beginRemoveRows(modelIdxOfDestinationSubTreeRoot, resultChildIdx, resultChildIdx); + destinationSubTreeRoot->removeChildren(resultChildIdx, 1); + this->endRemoveRows(); + resultChildIdx--; + } + } + + // Then loop over the children in the new ui tree, finding the corresponding items in the old tree. + // If they are found, we move them to the correct position. + // If not found, we pulls the item out of the old ui tree, inserting it into the new tree to avoid the default delete operation in ~UiTreeItem() + + int sourceChildCount = sourceSubTreeRoot->childCount(); + int sourceChildIdx = 0; + + for (int resultChildIdx = 0; resultChildIdx < sourceChildCount; ++resultChildIdx, ++sourceChildIdx) + { + PdmUiTreeItem* newChild = sourceSubTreeRoot->child(sourceChildIdx); + int childIndex = destinationSubTreeRoot->findChildItemIndex(newChild->dataObject()); + + if (childIndex == -1) // Not found + { + this->beginInsertRows(modelIdxOfDestinationSubTreeRoot, resultChildIdx, resultChildIdx); + destinationSubTreeRoot->insertChild(resultChildIdx, newChild); + this->endInsertRows(); + sourceSubTreeRoot->removeChildrenNoDelete(sourceChildIdx, 1); + sourceChildIdx--; + } + else if (childIndex != resultChildIdx) // Found, but must be moved + { + assert(childIndex > resultChildIdx); + + PdmUiTreeItem* oldChild = destinationSubTreeRoot->child(childIndex); + this->beginMoveRows(modelIdxOfDestinationSubTreeRoot, childIndex, childIndex, modelIdxOfDestinationSubTreeRoot, resultChildIdx); + destinationSubTreeRoot->removeChildrenNoDelete(childIndex, 1); + destinationSubTreeRoot->insertChild(resultChildIdx, oldChild); + this->endMoveRows(); + updateModelSubTree( index(resultChildIdx, 0, modelIdxOfDestinationSubTreeRoot), oldChild, newChild); + } + else // Found the corresponding item in the right place. + { + PdmUiTreeItem* oldChild = destinationSubTreeRoot->child(childIndex); + updateModelSubTree( index(resultChildIdx, 0, modelIdxOfDestinationSubTreeRoot), oldChild, newChild); + } + } + + +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTreeItem* PdmUiTreeViewModel::treeItemRoot() +{ + return m_treeItemRoot; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewModel::notifyModelChanged() +{ + QModelIndex startModelIdx = index(0,0); + QModelIndex endModelIdx = index(rowCount(startModelIdx), 0); + + emit dataChanged(startModelIdx, endModelIdx); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QVariant PdmUiTreeViewModel::headerData(int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole */) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (section < m_columnHeaders.size()) + { + return m_columnHeaders[section]; + } + + return QVariant(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewModel::setColumnHeaders(const QStringList& columnHeaders) +{ + m_columnHeaders = columnHeaders; +} + + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTreeItem* caf::PdmUiTreeViewModel::getTreeItemFromIndex(const QModelIndex& index) +{ + if (index.isValid()) + { + assert(index.internalPointer()); + + PdmUiTreeItem* treeItem = static_cast(index.internalPointer()); + return treeItem; + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QModelIndex caf::PdmUiTreeViewModel::getModelIndexFromPdmObjectRecursive(const QModelIndex& currentIndex, const PdmObject * object) const +{ + if (currentIndex.internalPointer()) + { + PdmUiTreeItem* treeItem = static_cast(currentIndex.internalPointer()); + if (treeItem->dataObject()->object() == object) return currentIndex; + } + + int row; + for (row = 0; row < rowCount(currentIndex); ++row) + { + QModelIndex foundIndex = getModelIndexFromPdmObjectRecursive(index(row, 0, currentIndex), object); + if (foundIndex.isValid()) return foundIndex; + } + return QModelIndex(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QModelIndex caf::PdmUiTreeViewModel::getModelIndexFromPdmObject( const PdmObject * object) const +{ + QModelIndex foundIndex; + int numRows = rowCount(QModelIndex()); + int r = 0; + while (r < numRows && !foundIndex.isValid()) + { + foundIndex = getModelIndexFromPdmObjectRecursive(index(r, 0, QModelIndex()), object); + ++r; + } + return foundIndex; +} + + + + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h new file mode 100644 index 0000000000..c8a1028be6 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h @@ -0,0 +1,114 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafUiTreeItem.h" + +#include +#include + +#include +#include "cafPdmPointer.h" + + +namespace caf +{ + +class PdmObject; + +//typedef UiTreeItem > PdmUiTreeItem; +class PdmUiTreeOrdering; +typedef UiTreeItem PdmUiTreeItem; +//================================================================================================== +// +// This class is intended to replace UiTreeModelPdm (cafUiTreeModelPdm) +// +//================================================================================================== +class PdmUiTreeViewModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + PdmUiTreeViewModel(QObject* parent); + + void setTreeItemRoot(PdmUiTreeItem* root); + PdmUiTreeItem* treeItemRoot(); + + void emitDataChanged(const QModelIndex& index); + + static PdmUiTreeItem* getTreeItemFromIndex(const QModelIndex& index); + QModelIndex getModelIndexFromPdmObject(const PdmObject* object) const; + void updateUiSubTree(PdmObject* root); + + void notifyModelChanged(); + void setColumnHeaders(const QStringList& columnHeaders); + +public: + // Overrides from QAbstractItemModel + virtual QModelIndex index(int row, int column, const QModelIndex &parentIndex = QModelIndex( )) const; + virtual QModelIndex parent(const QModelIndex &index) const; + virtual int rowCount(const QModelIndex &parentIndex = QModelIndex( ) ) const; + virtual int columnCount(const QModelIndex &parentIndex = QModelIndex( ) ) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole ) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; + + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + +protected: + QModelIndex getModelIndexFromPdmObjectRecursive(const QModelIndex& currentIndex, const PdmObject * object) const; +private: + void updateModelSubTree(const QModelIndex& uiSubTreeRootModelIdx, PdmUiTreeItem* uiModelSubTreeRoot, PdmUiTreeItem* updatedPdmSubTreeRoot); + + PdmUiTreeItem* m_treeItemRoot; + QStringList m_columnHeaders; +}; + + + +//================================================================================================== +/// +//================================================================================================== +class UiTreeItemBuilderPdm +{ +public: + static PdmUiTreeItem* buildViewItems(PdmUiTreeItem* parentTreeItem, int position, caf::PdmObject* object); +}; + +} // End of namespace caf diff --git a/Fwk/VizFwk/CMake/Utils/ceeDetermineCompilerFlags.cmake b/Fwk/VizFwk/CMake/Utils/ceeDetermineCompilerFlags.cmake index 1ec1cd18d3..ae8dc3fcbb 100644 --- a/Fwk/VizFwk/CMake/Utils/ceeDetermineCompilerFlags.cmake +++ b/Fwk/VizFwk/CMake/Utils/ceeDetermineCompilerFlags.cmake @@ -69,7 +69,11 @@ if (MSVC) # Setup the our STRICT compile flags # These are the flags we would like to use on all of our own libraries - set(CEE_STRICT_CXX_FLAGS "${CEE_BASE_CXX_FLAGS} /Wall") + if (${MSVC_VERSION} LESS 1600) + set(CEE_STRICT_CXX_FLAGS "${CEE_BASE_CXX_FLAGS} /W4") + elseif() + set(CEE_STRICT_CXX_FLAGS "${CEE_BASE_CXX_FLAGS} /Wall") + endif() # Must add base warning level after setting up strict set(CEE_BASE_CXX_FLAGS "${CEE_BASE_CXX_FLAGS} /W3") diff --git a/Fwk/VizFwk/CMakeLists.txt b/Fwk/VizFwk/CMakeLists.txt index 2b45bb33c1..a799c645e1 100644 --- a/Fwk/VizFwk/CMakeLists.txt +++ b/Fwk/VizFwk/CMakeLists.txt @@ -23,6 +23,13 @@ if (CEE_STAND_ALONE) endif() +# Allow use of non-threadsafe reference counter in cvf::Object on systems with no atomics support +option(CEE_WORKAROUND_ON_SYSTEMS_WITHOUT_ATOMICS "Allow use of non-threadsafe reference counter on systems with no atomics support" OFF) +if (CEE_WORKAROUND_ON_SYSTEMS_WITHOUT_ATOMICS) + add_definitions(-DCVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS) +endif() + + add_subdirectory(LibCore) add_subdirectory(LibIo) add_subdirectory(LibGeometry) diff --git a/Fwk/VizFwk/LibCore/CMakeLists.txt b/Fwk/VizFwk/LibCore/CMakeLists.txt index 4ec1da4fab..3ce19f6ec0 100644 --- a/Fwk/VizFwk/LibCore/CMakeLists.txt +++ b/Fwk/VizFwk/LibCore/CMakeLists.txt @@ -6,13 +6,13 @@ project(LibCore) # Use our strict compile flags set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_STRICT_CXX_FLAGS}") - set(CEE_HEADER_FILES cvfArray.h cvfArray.inl cvfArrayWrapperConst.h cvfArrayWrapperToEdit.h cvfAssert.h +cvfAtomicCounter.h cvfBase.h cvfBase64.h cvfCharArray.h @@ -68,6 +68,7 @@ cvfVersion.h set(CEE_SOURCE_FILES cvfAssert.cpp +cvfAtomicCounter.cpp cvfBase64.cpp cvfCharArray.cpp cvfCodeLocation.cpp diff --git a/Fwk/VizFwk/LibCore/LibCore.vcxproj b/Fwk/VizFwk/LibCore/LibCore.vcxproj index 99bf0ca399..2e5f67e714 100644 --- a/Fwk/VizFwk/LibCore/LibCore.vcxproj +++ b/Fwk/VizFwk/LibCore/LibCore.vcxproj @@ -232,6 +232,7 @@ + @@ -290,6 +291,7 @@ + diff --git a/Fwk/VizFwk/LibCore/LibCore.vcxproj.filters b/Fwk/VizFwk/LibCore/LibCore.vcxproj.filters index 3146204a04..5d549ba813 100644 --- a/Fwk/VizFwk/LibCore/LibCore.vcxproj.filters +++ b/Fwk/VizFwk/LibCore/LibCore.vcxproj.filters @@ -45,6 +45,7 @@ + @@ -90,5 +91,6 @@ + - + \ No newline at end of file diff --git a/Fwk/VizFwk/LibCore/cvfArrayWrapperConst.h b/Fwk/VizFwk/LibCore/cvfArrayWrapperConst.h index 88049066b0..4d24812bf2 100644 --- a/Fwk/VizFwk/LibCore/cvfArrayWrapperConst.h +++ b/Fwk/VizFwk/LibCore/cvfArrayWrapperConst.h @@ -151,3 +151,4 @@ inline const ArrayWrapperConst< const ElmType*, ElmType > wrapArrayConst( ElmTy } } + diff --git a/Fwk/VizFwk/LibCore/cvfArrayWrapperToEdit.h b/Fwk/VizFwk/LibCore/cvfArrayWrapperToEdit.h index 4ac8558734..5f2ae1fc61 100644 --- a/Fwk/VizFwk/LibCore/cvfArrayWrapperToEdit.h +++ b/Fwk/VizFwk/LibCore/cvfArrayWrapperToEdit.h @@ -130,3 +130,4 @@ inline ArrayWrapperToEdit< ElmType*, ElmType > wrapArrayToEdit(ElmType* array, s } } + diff --git a/Fwk/VizFwk/LibCore/cvfAssert.cpp b/Fwk/VizFwk/LibCore/cvfAssert.cpp index bc74657cb5..8e33fcd7ea 100644 --- a/Fwk/VizFwk/LibCore/cvfAssert.cpp +++ b/Fwk/VizFwk/LibCore/cvfAssert.cpp @@ -113,9 +113,11 @@ Assert::FailAction AssertHandlerConsole::handleAssert(const char* fileName, int // Does the job on both Windows and Linux (creates a console on Windows if one doesn't exist) reportToConsole(fileName, lineNumber, expr, msg); -#ifdef WIN32 - if (::IsDebuggerPresent()) - { +#ifdef _MSC_VER +#if (_MSC_VER >= 1600) + if (::IsDebuggerPresent()) +#endif + { __debugbreak(); } #endif diff --git a/Fwk/VizFwk/LibCore/cvfAtomicCounter.cpp b/Fwk/VizFwk/LibCore/cvfAtomicCounter.cpp new file mode 100644 index 0000000000..4d1768f0fd --- /dev/null +++ b/Fwk/VizFwk/LibCore/cvfAtomicCounter.cpp @@ -0,0 +1,193 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cvfAtomicCounter.h" + +// Some older GCC version do not support atomics, we have seen this for RHEL5 +#if defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS) + +namespace cvf { + +#ifdef WIN32 +#pragma warning (push) +#pragma warning (disable: 4668) +#include +#pragma warning (pop) + + +AtomicCounter::AtomicCounter(int initialValue) + : m_counter(initialValue) +{ +} + + +AtomicCounter::~AtomicCounter() +{ +} + + +AtomicCounter::operator int () const +{ + return m_counter; +} + +int AtomicCounter::operator ++ () // prefix +{ + return InterlockedIncrement(&m_counter); +} + + +int AtomicCounter::operator ++ (int) // postfix +{ + int result = InterlockedIncrement(&m_counter); + return --result; +} + + +int AtomicCounter::operator -- () // prefix +{ + return InterlockedDecrement(&m_counter); +} + + +int AtomicCounter::operator -- (int) // postfix +{ + int result = InterlockedDecrement(&m_counter); + return ++result; +} + + +#elif defined(CVF_IOS) || defined(CVF_OSX) + +AtomicCounter::AtomicCounter(int initialValue) + : m_counter(initialValue) +{ +} + + +AtomicCounter::AtomicCounter(const AtomicCounter& counter) + : m_counter(counter.value()) +{ +} + + +AtomicCounter::~AtomicCounter() +{ +} + +AtomicCounter::operator int () const +{ + return m_counter; +} + + +int AtomicCounter::operator ++ () // prefix +{ + return OSAtomicIncrement32(&m_counter); +} + + +int AtomicCounter::operator ++ (int) // postfix +{ + int result = OSAtomicIncrement32(&m_counter); + return --result; +} + + +int AtomicCounter::operator -- () // prefix +{ + return OSAtomicDecrement32(&m_counter); +} + + +int AtomicCounter::operator -- (int) // postfix +{ + int result = OSAtomicDecrement32(&m_counter); + return ++result; +} + + +#elif defined(CVF_HAVE_GCC_ATOMICS) + + +AtomicCounter::AtomicCounter(int initialValue) + : m_counter(initialValue) +{ +} + +AtomicCounter::~AtomicCounter() +{ +} + +AtomicCounter::operator int () const +{ + return m_counter; +} + + +int AtomicCounter::operator ++ () // prefix +{ + return __sync_add_and_fetch(&m_counter, 1); +} + + +int AtomicCounter::operator ++ (int) // postfix +{ + return __sync_fetch_and_add(&m_counter, 1); +} + + +int AtomicCounter::operator -- () // prefix +{ + return __sync_sub_and_fetch(&m_counter, 1); +} + + +int AtomicCounter::operator -- (int) // postfix +{ + return __sync_fetch_and_sub(&m_counter, 1); +} + + +#endif + + +} // namespace cvf + + + +#endif // CVF_ATOMICS_COMPILED diff --git a/Fwk/VizFwk/LibCore/cvfAtomicCounter.h b/Fwk/VizFwk/LibCore/cvfAtomicCounter.h new file mode 100644 index 0000000000..eef1eb38f7 --- /dev/null +++ b/Fwk/VizFwk/LibCore/cvfAtomicCounter.h @@ -0,0 +1,96 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cvfBase.h" + +#ifdef WIN32 + #define CVF_ATOMIC_COUNTER_CLASS_EXISTS +#elif defined(CVF_IOS) || defined(CVF_OSX) + #include + #define CVF_ATOMIC_COUNTER_CLASS_EXISTS +#elif defined __GNUC__ + #if (CVF_GCC_VER >= 40200) && (defined(__x86_64__) || defined(__i386__)) + #define CVF_HAVE_GCC_ATOMICS + #define CVF_ATOMIC_COUNTER_CLASS_EXISTS + #elif (CVF_GCC_VER >= 40300) + #define CVF_HAVE_GCC_ATOMICS + #define CVF_ATOMIC_COUNTER_CLASS_EXISTS + #endif +#endif + +#if defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS) + +namespace cvf { + +// Inspired by Poco + + +class AtomicCounter +{ +public: + explicit AtomicCounter(int initialValue); + ~AtomicCounter(); + + operator int () const; + + int operator ++ (); // prefix + int operator ++ (int); // postfix + + int operator -- (); // prefix + int operator -- (int); // postfix + +private: + + CVF_DISABLE_COPY_AND_ASSIGN(AtomicCounter); + +#ifdef WIN32 + typedef volatile long ImplType; +#elif defined(CVF_IOS) || defined(CVF_OSX) + typedef int32_t ImplType; +#else + typedef int ImplType; +#endif + + ImplType m_counter; +}; + + +} // namespace cvf + +#endif diff --git a/Fwk/VizFwk/LibCore/cvfBase.h b/Fwk/VizFwk/LibCore/cvfBase.h index 30970d05fb..6b6e8bf6e6 100644 --- a/Fwk/VizFwk/LibCore/cvfBase.h +++ b/Fwk/VizFwk/LibCore/cvfBase.h @@ -44,7 +44,7 @@ // Global include file with definitions useful for all library files // Disable some annoying warnings so we can compile with warning level Wall -#ifdef WIN32 +#ifdef _MSC_VER // 4512 'class' : assignment operator could not be generated : Due to problems with classes with reference member variables (e.g. VertexCompactor) // 4514 unreferenced inline/local function has been removed // 4625 copy constructor could not be generated because a base class copy constructor is inaccessible @@ -54,13 +54,26 @@ // 4711 function 'func_name' selected for automatic inline expansion // 4738 storing 32-bit float result in memory, possible loss of performance // 4820 'bytes' bytes padding added after construct 'member_name' +#pragma warning (disable: 4512 4514 4625 4626 4640 4710 4711 4738 4820) + +#if (_MSC_VER >= 1600) +// VS2010 and newer // 4986 'operator new[]': exception specification does not match previous declaration -#pragma warning (disable: 4512 4514 4625 4626 4640 4710 4711 4738 4820 4986) +#pragma warning (disable: 4986) +#endif + #endif + +// Makes it easier to check on the current GCC version +#ifdef __GNUC__ +// 40302 means version 4.3.2. +# define CVF_GCC_VER (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) +#endif + // Helper macro to disable (ignore) compiler warnings on GCC // The needed pragma is only available in GCC for versions 4.2.x and above -#if defined __GNUC__ && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 402) +#if defined(__GNUC__) && (CVF_GCC_VER >= 40200) #define CVF_DO_PRAGMA(x) _Pragma(#x) #define CVF_GCC_DIAGNOSTIC_IGNORE(OPTION_STRING) CVF_DO_PRAGMA(GCC diagnostic ignored OPTION_STRING) #else diff --git a/Fwk/VizFwk/LibCore/cvfObject.h b/Fwk/VizFwk/LibCore/cvfObject.h index 9ff28e7ad6..264cab83af 100644 --- a/Fwk/VizFwk/LibCore/cvfObject.h +++ b/Fwk/VizFwk/LibCore/cvfObject.h @@ -41,6 +41,15 @@ #include +#include "cvfAtomicCounter.h" + +#if defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS) && defined(CVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS) +#error Two mutually exclusive defines detected : CVF_ATOMIC_COUNTER_CLASS_EXISTS && CVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS +#endif + +#if !defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS) && !defined(CVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS) +#error No support for atomics. Define CVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS to be able to compile +#endif namespace cvf { @@ -65,7 +74,13 @@ class Object static void dumpActiveObjectInstances(); private: + +#if defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS) + mutable AtomicCounter m_refCount; +#elif defined(CVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS) mutable int m_refCount; +#endif + CVF_DISABLE_COPY_AND_ASSIGN(Object); }; diff --git a/Fwk/VizFwk/LibCore/cvfObject.inl b/Fwk/VizFwk/LibCore/cvfObject.inl index a4c65fd573..59bf9dbf38 100644 --- a/Fwk/VizFwk/LibCore/cvfObject.inl +++ b/Fwk/VizFwk/LibCore/cvfObject.inl @@ -91,9 +91,7 @@ inline int Object::release() const CVF_TIGHT_ASSERT(m_refCount > 0); - m_refCount--; - - if (m_refCount == 0) + if (--m_refCount == 0) { delete this; return 0; diff --git a/Fwk/VizFwk/LibCore/cvfPlane.cpp b/Fwk/VizFwk/LibCore/cvfPlane.cpp index dcb523125a..7a39f37fc8 100644 --- a/Fwk/VizFwk/LibCore/cvfPlane.cpp +++ b/Fwk/VizFwk/LibCore/cvfPlane.cpp @@ -205,7 +205,7 @@ bool Plane::setFromPointAndNormal(const Vec3d& point, const Vec3d& normal) /// \param p2 Second point on the plane /// \param p3 Third point on the plane /// -/// \return true if successfully set. false if points are on the same line. +/// \return true if successfully set. false if points are on the same line. /// /// The three points must be different from each other and cannot be on the same line in space //-------------------------------------------------------------------------------------------------- @@ -322,7 +322,7 @@ double Plane::distanceToOrigin() const /// \param vector Vector to be projected /// \param projectedVector Projected vector to be returned by pointer /// -/// \return true if successfully projected. +/// \return true if successfully projected. /// false if the given \a vector is parallel with the plane's normal //-------------------------------------------------------------------------------------------------- bool Plane::projectVector(const Vec3d& vector, Vec3d* projectedVector) const @@ -378,7 +378,7 @@ Vec3d Plane::projectPoint(const Vec3d& point) const /// \param point Point on line /// \param direction Normalized direction of line /// -/// \return true if success. false if direction is zero -> no point of intersection exists +/// \return true if success. false if direction is zero -> no point of intersection exists //-------------------------------------------------------------------------------------------------- bool Plane::intersect(const Plane& other, Vec3d* point, Vec3d* direction) const { @@ -474,6 +474,125 @@ bool Plane::intersect(const Vec3d& a, const Vec3d& b, Vec3d* intersection) const return false; } + + +//-------------------------------------------------------------------------------------------------- +/// Clip a triangle against this plane +/// +/// Clip the triangle given by parameters a, b and c against this plane. The vertices of the +/// resulting clipped polygon (triangle or quad) will be returned in \a clippedPolygon. Since the +/// clipped polygon may be a quad, the \a clippedPolygon array must have room for at least 4 elements. +/// +/// \return The number of resulting vertices that are populated in \a clippedPolygon. Will be 0, 3 or 4. +//-------------------------------------------------------------------------------------------------- +size_t Plane::clipTriangle(const Vec3d& a, const Vec3d& b, const Vec3d& c, Vec3d clippedPolygon[4]) const +{ + // Except for the trivial cases where all vertices are in front + // or behind plane, these are the permutations + // + // Single vertex on positive side of plane + // => return a triangle + // + // +\ /\c /\c /+ /\c . + // \ / \ / \ / + / \ + . + // \ \ / \/ ---/----\--- . + // / \ \ / /\ / \ . + // a/___\____\b a/_____/__\b a/________\b . + // +\ /+ + // + // Two vertices vertex on positive side of plane + // => return a quad + // + // /\c \+ /\c /\c +/ . + // / \ \ / \ / \ / . + // ___/____\___ \ \ / \/ . + // + / \ + / \ \ / /\ . + // a/________\b a/___\____\b a/_____/__\b . + // \+ +/ + + bool onPosSide[3]; + onPosSide[0] = distanceSquared(a) >= 0 ? true : false; + onPosSide[1] = distanceSquared(b) >= 0 ? true : false; + onPosSide[2] = distanceSquared(c) >= 0 ? true : false; + const int numPositiveVertices = (onPosSide[0] ? 1 : 0) + (onPosSide[1] ? 1 : 0) + (onPosSide[2] ? 1 : 0); + + // The entire triangle is on the negative side + // Clip everything + if (numPositiveVertices == 0) + { + return 0; + } + + // All triangle vertices are on the positive side + // Return the same triangle + if (numPositiveVertices == 3) + { + clippedPolygon[0] = a; + clippedPolygon[1] = b; + clippedPolygon[2] = c; + return 3; + } + + // Handle case where a single vertex is on the positive side + // Will result in the return of a single clipped triangle + if (numPositiveVertices == 1) + { + if (onPosSide[0]) + { + clippedPolygon[0] = a; + intersect(a, b, &clippedPolygon[1]); + intersect(a, c, &clippedPolygon[2]); + } + else if (onPosSide[1]) + { + clippedPolygon[0] = b; + intersect(b, c, &clippedPolygon[1]); + intersect(b, a, &clippedPolygon[2]); + } + else + { + CVF_ASSERT(onPosSide[2]); + clippedPolygon[0] = c; + intersect(c, a, &clippedPolygon[1]); + intersect(c, b, &clippedPolygon[2]); + } + + return 3; + } + else + { + CVF_ASSERT(numPositiveVertices == 2); + if (onPosSide[0] && onPosSide[1]) + { + // a & b are on positive side + clippedPolygon[0] = a; + clippedPolygon[1] = b; + intersect(b, c, &clippedPolygon[2]); + intersect(a, c, &clippedPolygon[3]); + } + else if (onPosSide[1] && onPosSide[2]) + { + // b & c are on positive side + clippedPolygon[0] = b; + clippedPolygon[1] = c; + intersect(c, a, &clippedPolygon[2]); + intersect(b, a, &clippedPolygon[3]); + } + else + { + // c && a are on positive side + CVF_ASSERT(onPosSide[2] && onPosSide[0]); + clippedPolygon[0] = c; + clippedPolygon[1] = a; + intersect(a, b, &clippedPolygon[2]); + intersect(c, b, &clippedPolygon[3]); + } + + return 4; + } +} + + //-------------------------------------------------------------------------------------------------- /// Classify where the point is located relative to the plane /// diff --git a/Fwk/VizFwk/LibCore/cvfPlane.h b/Fwk/VizFwk/LibCore/cvfPlane.h index 0ce4614d69..c44bf8ebee 100644 --- a/Fwk/VizFwk/LibCore/cvfPlane.h +++ b/Fwk/VizFwk/LibCore/cvfPlane.h @@ -91,7 +91,8 @@ class Plane : public Object bool intersect(const Plane& other, Vec3d* point, Vec3d* direction = NULL) const; bool intersect(const Vec3d& a, const Vec3d& b, Vec3d* intersection) const; - + size_t clipTriangle(const Vec3d& ta, const Vec3d& tb, const Vec3d& tc, Vec3d clippedPolygon[4]) const; + Side side(const Vec3d& point) const; Side side(const Vec3dArray& points) const; diff --git a/Fwk/VizFwk/LibCore/cvfVector2.h b/Fwk/VizFwk/LibCore/cvfVector2.h index 0bf1806b67..720dceab45 100644 --- a/Fwk/VizFwk/LibCore/cvfVector2.h +++ b/Fwk/VizFwk/LibCore/cvfVector2.h @@ -108,6 +108,8 @@ class Vector2 inline S lengthSquared() const; bool setLength(S newLength); + const Vector2 perpendicularVector() const; + public: static const Vector2 X_AXIS; ///< X axis vector <1, 0> static const Vector2 Y_AXIS; ///< Y axis vector <0, 1> diff --git a/Fwk/VizFwk/LibCore/cvfVector2.inl b/Fwk/VizFwk/LibCore/cvfVector2.inl index 7a74ae73d2..90271c2c16 100644 --- a/Fwk/VizFwk/LibCore/cvfVector2.inl +++ b/Fwk/VizFwk/LibCore/cvfVector2.inl @@ -394,6 +394,27 @@ bool Vector2::setLength(S newLength) } +//-------------------------------------------------------------------------------------------------- +/// Return a unit length perpendicular vector +/// +/// Returns the vector (y,-x), normalized. This can be thought of as the 'right' vector. +//-------------------------------------------------------------------------------------------------- +template +const Vector2 Vector2::perpendicularVector() const +{ + S len = length(); + if (len > 0.0) + { + S oneOverLen = (static_cast(1.0)/len); + return Vector2(m_v[1]*oneOverLen, -m_v[0]*oneOverLen); + } + else + { + return Vector2::ZERO; + } +} + + //-------------------------------------------------------------------------------------------------- /// Normalize the vector (make sure the length is 1.0). /// diff --git a/Fwk/VizFwk/LibGeometry/CMakeLists.txt b/Fwk/VizFwk/LibGeometry/CMakeLists.txt index 20eceb2ff9..6034118a2c 100644 --- a/Fwk/VizFwk/LibGeometry/CMakeLists.txt +++ b/Fwk/VizFwk/LibGeometry/CMakeLists.txt @@ -25,6 +25,7 @@ cvfLibGeometry.h cvfMeshEdgeExtractor.h cvfOutlineEdgeExtractor.h cvfPatchGenerator.h +cvfPrimitiveTests.h cvfRay.h cvfTriangleMeshEdgeExtractor.h cvfTriangleVertexSplitter.h @@ -46,6 +47,7 @@ cvfGeometryUtils.cpp cvfMeshEdgeExtractor.cpp cvfOutlineEdgeExtractor.cpp cvfPatchGenerator.cpp +cvfPrimitiveTests.cpp cvfRay.cpp cvfTriangleMeshEdgeExtractor.cpp cvfTriangleVertexSplitter.cpp diff --git a/Fwk/VizFwk/LibGeometry/LibGeometry.vcxproj b/Fwk/VizFwk/LibGeometry/LibGeometry.vcxproj index 1ab7b75a2e..fdea6f8510 100644 --- a/Fwk/VizFwk/LibGeometry/LibGeometry.vcxproj +++ b/Fwk/VizFwk/LibGeometry/LibGeometry.vcxproj @@ -253,6 +253,7 @@ + @@ -273,6 +274,7 @@ + diff --git a/Fwk/VizFwk/LibGeometry/LibGeometry.vcxproj.filters b/Fwk/VizFwk/LibGeometry/LibGeometry.vcxproj.filters index 3ea51aeeb0..c5b73ae9b8 100644 --- a/Fwk/VizFwk/LibGeometry/LibGeometry.vcxproj.filters +++ b/Fwk/VizFwk/LibGeometry/LibGeometry.vcxproj.filters @@ -20,6 +20,7 @@ + @@ -43,5 +44,6 @@ + \ No newline at end of file diff --git a/Fwk/VizFwk/LibGeometry/cvfPrimitiveTests.cpp b/Fwk/VizFwk/LibGeometry/cvfPrimitiveTests.cpp new file mode 100644 index 0000000000..4dc0f2ba83 --- /dev/null +++ b/Fwk/VizFwk/LibGeometry/cvfPrimitiveTests.cpp @@ -0,0 +1,106 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cvfBase.h" +#include "cvfPrimitiveTests.h" + +#include + +namespace cvf { + + + +//================================================================================================== +/// +/// \class cvf::PrimitiveTests +/// \ingroup Geometry +/// +/// +/// +//================================================================================================== + + + +//-------------------------------------------------------------------------------------------------- +/// Calculate intersection between the lines p1p2 and p3p4 +//-------------------------------------------------------------------------------------------------- +bool PrimitiveTests::intersectLines(const Vec2d& p1, const Vec2d& p2, const Vec2d& p3, const Vec2d& p4, Vec2d* isect) +{ + // See Paul Bourke, Intersection point of two lines in 2 dimensions + + const double epsilon = std::numeric_limits::epsilon(); + + const double denom = (p4.y()-p3.y())*(p2.x()-p1.x()) - (p4.x()-p3.x())*(p2.y()-p1.y()); + const double numera = (p4.x()-p3.x())*(p1.y()-p3.y()) - (p4.y()-p3.y())*(p1.x()-p3.x()); + const double numerb = (p2.x()-p1.x())*(p1.y()-p3.y()) - (p2.y()-p1.y())*(p1.x()-p3.x()); + + // Are the lines coincident? + if (cvf::Math::abs(numera) < epsilon && + cvf::Math::abs(numerb) < epsilon && + cvf::Math::abs(denom) < epsilon) + { + isect->x() = (p1.x() + p2.x()) / 2; + isect->y() = (p1.y() + p2.y()) / 2; + return true; + } + + // Are the lines parallel? + if (cvf::Math::abs(denom) < epsilon) + { + isect->setZero(); + return false; + } + + const double ta = numera/denom; +// const double tb = numerb/denom; +// +// // Is the intersection along the the segments ? +// if (ta < 0 || ta > 1 || tb < 0 || tb > 1) +// { +// isect->setZero(); +// return false; +// } + + isect->x() = p1.x() + ta * (p2.x() - p1.x()); + isect->y() = p1.y() + ta * (p2.y() - p1.y()); + + return true; + +} + + +} // namespace cvf diff --git a/Fwk/VizFwk/LibGeometry/cvfPrimitiveTests.h b/Fwk/VizFwk/LibGeometry/cvfPrimitiveTests.h new file mode 100644 index 0000000000..a366ff6818 --- /dev/null +++ b/Fwk/VizFwk/LibGeometry/cvfPrimitiveTests.h @@ -0,0 +1,56 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cvfVector2.h" + +namespace cvf { + + +//================================================================================================== +// +// +// +//================================================================================================== +class PrimitiveTests +{ +public: + static bool intersectLines(const Vec2d& p1, const Vec2d& p2, const Vec2d& p3, const Vec2d& p4, Vec2d* isect); +}; + +} diff --git a/Fwk/VizFwk/LibGuiQt/cvfqtMouseState.h b/Fwk/VizFwk/LibGuiQt/cvfqtMouseState.h index 406c6909a0..fc6c39cafc 100644 --- a/Fwk/VizFwk/LibGuiQt/cvfqtMouseState.h +++ b/Fwk/VizFwk/LibGuiQt/cvfqtMouseState.h @@ -40,7 +40,8 @@ class QMouseEvent; class QGraphicsSceneMouseEvent; -#include +#include + namespace cvfqt { diff --git a/Fwk/VizFwk/LibRender/LibRender.vcxproj b/Fwk/VizFwk/LibRender/LibRender.vcxproj index d83878465b..0aeca74699 100644 --- a/Fwk/VizFwk/LibRender/LibRender.vcxproj +++ b/Fwk/VizFwk/LibRender/LibRender.vcxproj @@ -463,7 +463,12 @@ Document - + + Document + + + Document + diff --git a/Fwk/VizFwk/LibRender/LibRender.vcxproj.filters b/Fwk/VizFwk/LibRender/LibRender.vcxproj.filters index 3b5dabfa44..c511a1afa1 100644 --- a/Fwk/VizFwk/LibRender/LibRender.vcxproj.filters +++ b/Fwk/VizFwk/LibRender/LibRender.vcxproj.filters @@ -186,15 +186,18 @@ + + glsl + + + glsl + glsl - - glsl - diff --git a/Fwk/VizFwk/LibRender/cvfShaderSourceRepository.cpp b/Fwk/VizFwk/LibRender/cvfShaderSourceRepository.cpp index 66a011a8c3..67eee1594c 100644 --- a/Fwk/VizFwk/LibRender/cvfShaderSourceRepository.cpp +++ b/Fwk/VizFwk/LibRender/cvfShaderSourceRepository.cpp @@ -119,6 +119,7 @@ const char* ShaderSourceRepository::shaderIdentString(ShaderIdent shaderIdent) CVF_IDENT_HANDLE_CASE(src_TextureGlobalAlpha); CVF_IDENT_HANDLE_CASE(src_TextureFromPointCoord); CVF_IDENT_HANDLE_CASE(src_TextureRectFromFragCoord_v33); + CVF_IDENT_HANDLE_CASE(src_VaryingColorGlobalAlpha); CVF_IDENT_HANDLE_CASE(light_Phong); CVF_IDENT_HANDLE_CASE(light_PhongDual); @@ -179,6 +180,7 @@ bool ShaderSourceRepository::rawShaderSource(ShaderIdent shaderIdent, CharArray* CVF_SOURCE_HANDLE_CASE(src_TextureGlobalAlpha); CVF_SOURCE_HANDLE_CASE(src_TextureFromPointCoord); CVF_SOURCE_HANDLE_CASE(src_TextureRectFromFragCoord_v33); + CVF_SOURCE_HANDLE_CASE(src_VaryingColorGlobalAlpha); CVF_SOURCE_HANDLE_CASE(light_Phong); CVF_SOURCE_HANDLE_CASE(light_PhongDual); diff --git a/Fwk/VizFwk/LibRender/cvfShaderSourceRepository.h b/Fwk/VizFwk/LibRender/cvfShaderSourceRepository.h index e20c7a4870..bacf13cb42 100644 --- a/Fwk/VizFwk/LibRender/cvfShaderSourceRepository.h +++ b/Fwk/VizFwk/LibRender/cvfShaderSourceRepository.h @@ -64,6 +64,7 @@ class ShaderSourceRepository : public Object src_TextureGlobalAlpha, src_TextureFromPointCoord, src_TextureRectFromFragCoord_v33, + src_VaryingColorGlobalAlpha, light_Phong, light_PhongDual, diff --git a/Fwk/VizFwk/LibRender/cvfShaderSourceStrings.h b/Fwk/VizFwk/LibRender/cvfShaderSourceStrings.h index ac3c2b8bb8..c6a027a8ab 100644 --- a/Fwk/VizFwk/LibRender/cvfShaderSourceStrings.h +++ b/Fwk/VizFwk/LibRender/cvfShaderSourceStrings.h @@ -914,6 +914,24 @@ static const char src_TwoSidedColor_inl[] = +//############################################################################################################################# +//############################################################################################################################# +static const char src_VaryingColorGlobalAlpha_inl[] = +" \n" +"uniform float u_alpha; \n" +" \n" +"varying vec4 v_color; \n" +" \n" +"//-------------------------------------------------------------------------------------------------- \n" +"/// RGB color from varying, alpha from uniform \n" +"//-------------------------------------------------------------------------------------------------- \n" +"vec4 srcFragment() \n" +"{ \n" +" return vec4(v_color.rgb, u_alpha); \n" +"} \n"; + + + //############################################################################################################################# //############################################################################################################################# static const char vs_DistanceScaledPoints_inl[] = @@ -1147,10 +1165,12 @@ static const char vs_Standard_inl[] = "attribute vec4 cvfa_vertex; \n" "attribute vec3 cvfa_normal; \n" "attribute vec2 cvfa_texCoord; \n" +"attribute vec4 cvfa_color; \n" " \n" "varying vec3 v_ecPosition; \n" "varying vec3 v_ecNormal; \n" "varying vec2 v_texCoord; \n" +"varying vec4 v_color; \n" " \n" "//-------------------------------------------------------------------------------------------------- \n" "/// Vertex Shader - Standard \n" @@ -1165,6 +1185,7 @@ static const char vs_Standard_inl[] = " v_ecPosition = (cvfu_modelViewMatrix * cvfa_vertex).xyz; \n" " v_ecNormal = cvfu_normalMatrix * cvfa_normal; \n" " v_texCoord = cvfa_texCoord; \n" +" v_color = cvfa_color; \n" " \n" "#ifdef CVF_CALC_CLIP_DISTANCES_IMPL \n" " calcClipDistances(vec4(v_ecPosition, 1)); \n" diff --git a/Fwk/VizFwk/LibRender/glsl/src_VaryingColorGlobalAlpha.glsl b/Fwk/VizFwk/LibRender/glsl/src_VaryingColorGlobalAlpha.glsl new file mode 100644 index 0000000000..d316fd0a9c --- /dev/null +++ b/Fwk/VizFwk/LibRender/glsl/src_VaryingColorGlobalAlpha.glsl @@ -0,0 +1,12 @@ + +uniform float u_alpha; + +varying vec4 v_color; + +//-------------------------------------------------------------------------------------------------- +/// RGB color from varying, alpha from uniform +//-------------------------------------------------------------------------------------------------- +vec4 srcFragment() +{ + return vec4(v_color.rgb, u_alpha); +} \ No newline at end of file diff --git a/Fwk/VizFwk/LibRender/glsl/vs_Standard.glsl b/Fwk/VizFwk/LibRender/glsl/vs_Standard.glsl index d02613fb4f..0463877e69 100644 --- a/Fwk/VizFwk/LibRender/glsl/vs_Standard.glsl +++ b/Fwk/VizFwk/LibRender/glsl/vs_Standard.glsl @@ -6,10 +6,12 @@ uniform mat3 cvfu_normalMatrix; attribute vec4 cvfa_vertex; attribute vec3 cvfa_normal; attribute vec2 cvfa_texCoord; +attribute vec4 cvfa_color; varying vec3 v_ecPosition; varying vec3 v_ecNormal; varying vec2 v_texCoord; +varying vec4 v_color; //-------------------------------------------------------------------------------------------------- /// Vertex Shader - Standard @@ -24,6 +26,7 @@ void main () v_ecPosition = (cvfu_modelViewMatrix * cvfa_vertex).xyz; v_ecNormal = cvfu_normalMatrix * cvfa_normal; v_texCoord = cvfa_texCoord; + v_color = cvfa_color; #ifdef CVF_CALC_CLIP_DISTANCES_IMPL calcClipDistances(vec4(v_ecPosition, 1)); diff --git a/Fwk/VizFwk/LibUtilities/cvfuImageTga.cpp b/Fwk/VizFwk/LibUtilities/cvfuImageTga.cpp index 606742687d..5abf548a6e 100644 --- a/Fwk/VizFwk/LibUtilities/cvfuImageTga.cpp +++ b/Fwk/VizFwk/LibUtilities/cvfuImageTga.cpp @@ -1,7 +1,7 @@ //################################################################################################## // // Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS +// Copyright (C) Ceetron Solutions AS // // This library may be used under the terms of either the GNU General Public License or // the GNU Lesser General Public License as follows: @@ -44,12 +44,13 @@ #include #include -#ifdef CVF_LINUX CVF_GCC_DIAGNOSTIC_IGNORE("-Wconversion") + +// Apparently, this warning doesn't exist until GCC 4.5 +#if defined(__GNUC__) && (CVF_GCC_VER >= 40500) CVF_GCC_DIAGNOSTIC_IGNORE("-Wunused-result") #endif - namespace cvfu { using cvf::ref; diff --git a/Fwk/VizFwk/LibUtilities/cvfuImageTga.h b/Fwk/VizFwk/LibUtilities/cvfuImageTga.h index 4c3dbb1a3c..2afb3d8fb8 100644 --- a/Fwk/VizFwk/LibUtilities/cvfuImageTga.h +++ b/Fwk/VizFwk/LibUtilities/cvfuImageTga.h @@ -1,7 +1,7 @@ //################################################################################################## // // Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS +// Copyright (C) Ceetron Solutions AS // // This library may be used under the terms of either the GNU General Public License or // the GNU Lesser General Public License as follows: diff --git a/Fwk/VizFwk/LibViewing/cvfModelBasicList.cpp b/Fwk/VizFwk/LibViewing/cvfModelBasicList.cpp index 946aaa64f3..c9c56f2c7f 100644 --- a/Fwk/VizFwk/LibViewing/cvfModelBasicList.cpp +++ b/Fwk/VizFwk/LibViewing/cvfModelBasicList.cpp @@ -126,6 +126,16 @@ void ModelBasicList::removeAllParts() } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void ModelBasicList::shrinkPartCount(size_t newPartCount) +{ + CVF_ASSERT(newPartCount <= m_parts.size()); + m_parts.resize(newPartCount); +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/VizFwk/LibViewing/cvfModelBasicList.h b/Fwk/VizFwk/LibViewing/cvfModelBasicList.h index 4f26a5c04b..d4083a707b 100644 --- a/Fwk/VizFwk/LibViewing/cvfModelBasicList.h +++ b/Fwk/VizFwk/LibViewing/cvfModelBasicList.h @@ -60,6 +60,7 @@ class ModelBasicList : public Model size_t partCount() const; void removePart(Part* part); void removeAllParts(); + void shrinkPartCount(size_t newPartCount); virtual void findVisibleParts(PartRenderHintCollection* visibleParts, const Camera& camera, const CullSettings& cullSettings, uint enableMask); virtual void allParts(Collection* partCollection); diff --git a/Fwk/VizFwk/Tests/LibCore_UnitTests/CMakeLists.txt b/Fwk/VizFwk/Tests/LibCore_UnitTests/CMakeLists.txt index 6179f39079..d9bdf9d046 100644 --- a/Fwk/VizFwk/Tests/LibCore_UnitTests/CMakeLists.txt +++ b/Fwk/VizFwk/Tests/LibCore_UnitTests/CMakeLists.txt @@ -14,6 +14,7 @@ set(CEE_LIBS LibCore) set(CEE_SOURCE_FILES cvfArray-Test.cpp cvfArrayWrapper-Test.cpp +cvfAtomicCounter-Test.cpp cvfBase-Test.cpp cvfBase64-Test.cpp cvfCharArray-Test.cpp diff --git a/Fwk/VizFwk/Tests/LibCore_UnitTests/LibCore_UnitTests.vcxproj b/Fwk/VizFwk/Tests/LibCore_UnitTests/LibCore_UnitTests.vcxproj index f3df0af7a1..af7fad5028 100644 --- a/Fwk/VizFwk/Tests/LibCore_UnitTests/LibCore_UnitTests.vcxproj +++ b/Fwk/VizFwk/Tests/LibCore_UnitTests/LibCore_UnitTests.vcxproj @@ -251,6 +251,7 @@ + diff --git a/Fwk/VizFwk/Tests/LibCore_UnitTests/LibCore_UnitTests.vcxproj.filters b/Fwk/VizFwk/Tests/LibCore_UnitTests/LibCore_UnitTests.vcxproj.filters index ff7ac81000..2355343553 100644 --- a/Fwk/VizFwk/Tests/LibCore_UnitTests/LibCore_UnitTests.vcxproj.filters +++ b/Fwk/VizFwk/Tests/LibCore_UnitTests/LibCore_UnitTests.vcxproj.filters @@ -34,6 +34,7 @@ + @@ -41,4 +42,4 @@ - + \ No newline at end of file diff --git a/Fwk/VizFwk/Tests/LibCore_UnitTests/cvfArrayWrapper-Test.cpp b/Fwk/VizFwk/Tests/LibCore_UnitTests/cvfArrayWrapper-Test.cpp index da06193796..bb9cba7996 100644 --- a/Fwk/VizFwk/Tests/LibCore_UnitTests/cvfArrayWrapper-Test.cpp +++ b/Fwk/VizFwk/Tests/LibCore_UnitTests/cvfArrayWrapper-Test.cpp @@ -123,10 +123,10 @@ TEST(ArrayWrapperTest, AllSpecializations) siztCvfArray[0] = 0; siztCvfArray[1] = 1; - cvf::Array uintCvfArray(2); + cvf::Array uintCvfArray(2); uintCvfArray[0] = 0; uintCvfArray[1] = 1; - const cvf::Array& cuintCvfArray = uintCvfArray; + const cvf::Array& cuintCvfArray = uintCvfArray; size_t siztBarePtrArray[2] = {0, 1}; @@ -187,3 +187,4 @@ TEST(ArrayWrapperTest, AllSpecializations) EXPECT_EQ(0.0, doubleBarePtr[1]); EXPECT_EQ(1.0, doubleBarePtr[0]); } + diff --git a/Fwk/VizFwk/Tests/LibCore_UnitTests/cvfAtomicCounter-Test.cpp b/Fwk/VizFwk/Tests/LibCore_UnitTests/cvfAtomicCounter-Test.cpp new file mode 100644 index 0000000000..1899a2141b --- /dev/null +++ b/Fwk/VizFwk/Tests/LibCore_UnitTests/cvfAtomicCounter-Test.cpp @@ -0,0 +1,141 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + + +#include "cvfAtomicCounter.h" + +#ifdef CVF_ATOMIC_COUNTER_CLASS_EXISTS + +#include "cvfDebugTimer.h" +#include "cvfObject.h" +#include "cvfCollection.h" + +#include "gtest/gtest.h" + +using namespace cvf; + +class MyObj : public Object +{ +public: + MyObj() { num_ = 0; } + MyObj(int num) { num_ = num; } + + int num() const { return num_; } + void num(int num) { num_ = num; } + + bool operator<(const MyObj& rhs) + { + return num_ < rhs.num_; + } + +private: + int num_; +}; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(DISABLED_ObjectConstructionBenchmark, TestBasicObjectConstruction) +{ + int objectCount = 1000000; + int iterationCount = 5; + + String sNumber(objectCount); + String refCountTxt = String("TestBasicObjectConstruction : ") + sNumber; + DebugTimer tim(refCountTxt.toAscii().ptr()); + + for (int iteration = 0; iteration < iterationCount; iteration++) + { + for (int i = 0; i < objectCount; i++) + { + MyObj* r2 = new MyObj(); + + r2->addRef(); + r2->release(); + } + + tim.reportLapTimeMS(); + } +} + + + +class ObjectReferencingSharedObject : public Object +{ +public: + ObjectReferencingSharedObject() { } + + cvf::ref m_sharedObject; +}; + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(DISABLED_ObjectConstructionBenchmark, TestReferenceOtherObject) +{ + int objectCount = 1000000; + int iterationCount = 5; + + String sNumber(objectCount); + String refCountTxt = String("TestReferenceOtherObjectClass : ") + sNumber; + DebugTimer tim(refCountTxt.toAscii().ptr()); + + for (int iteration = 0; iteration < iterationCount; iteration++) + { + cvf::ref sharedObj = new MyObj(); + + std::vector< cvf::ref > col; + col.resize(objectCount); + + for (int i = 0; i < objectCount; i++) + { + cvf::ref newObj = new ObjectReferencingSharedObject(); + newObj->m_sharedObject = sharedObj.p(); + + col[i] = newObj; + } + + String sNumber(sharedObj->refCount()); + String refCountTxt = String("Shared object reference count : ") + sNumber; + + tim.reportLapTimeMS(refCountTxt.toAscii().ptr()); + } +} + + +#endif //#ifdef CVF_ATOMIC_COUNTER_CLASS_EXISTS diff --git a/Fwk/VizFwk/Tests/LibCore_UnitTests/cvfVector2-Test.cpp b/Fwk/VizFwk/Tests/LibCore_UnitTests/cvfVector2-Test.cpp index 74580e733e..8bde8cd375 100644 --- a/Fwk/VizFwk/Tests/LibCore_UnitTests/cvfVector2-Test.cpp +++ b/Fwk/VizFwk/Tests/LibCore_UnitTests/cvfVector2-Test.cpp @@ -365,6 +365,38 @@ TEST(Vector2Test, SetLength) } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(Vector2Test, perpendicularVector) +{ + { + const Vec2d v(0, 1); + const Vec2d perp = v.perpendicularVector(); + EXPECT_DOUBLE_EQ(1, perp.x()); + EXPECT_DOUBLE_EQ(0, perp.y()); + } + { + const Vec2d v(1, 0); + const Vec2d perp = v.perpendicularVector(); + EXPECT_DOUBLE_EQ(0, perp.x()); + EXPECT_DOUBLE_EQ(-1, perp.y()); + } + { + const Vec2d v(0, -2); + const Vec2d perp = v.perpendicularVector(); + EXPECT_DOUBLE_EQ(-1, perp.x()); + EXPECT_DOUBLE_EQ(0, perp.y()); + } + { + const Vec2d v(-3, 0); + const Vec2d perp = v.perpendicularVector(); + EXPECT_DOUBLE_EQ(0, perp.x()); + EXPECT_DOUBLE_EQ(1, perp.y()); + } +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/VizFwk/Tests/LibGeometry_UnitTests/CMakeLists.txt b/Fwk/VizFwk/Tests/LibGeometry_UnitTests/CMakeLists.txt index d7c1a6939d..3db9d045ff 100644 --- a/Fwk/VizFwk/Tests/LibGeometry_UnitTests/CMakeLists.txt +++ b/Fwk/VizFwk/Tests/LibGeometry_UnitTests/CMakeLists.txt @@ -26,6 +26,7 @@ cvfGeometryUtils-Test.cpp cvfMeshEdgeExtractor-Test.cpp cvfOutlineEdgeExtractor-Test.cpp cvfPatchGenerator-Test.cpp +cvfPrimitiveTests-Test.cpp cvfRay-Test.cpp cvfTriangleMeshEdgeExtractor-Test.cpp cvfTriangleVertexSplitter-Test.cpp diff --git a/Fwk/VizFwk/Tests/LibGeometry_UnitTests/LibGeometry_UnitTests.vcxproj b/Fwk/VizFwk/Tests/LibGeometry_UnitTests/LibGeometry_UnitTests.vcxproj index 5fa9ba7f0b..db6873009a 100644 --- a/Fwk/VizFwk/Tests/LibGeometry_UnitTests/LibGeometry_UnitTests.vcxproj +++ b/Fwk/VizFwk/Tests/LibGeometry_UnitTests/LibGeometry_UnitTests.vcxproj @@ -262,6 +262,7 @@ + diff --git a/Fwk/VizFwk/Tests/LibGeometry_UnitTests/LibGeometry_UnitTests.vcxproj.filters b/Fwk/VizFwk/Tests/LibGeometry_UnitTests/LibGeometry_UnitTests.vcxproj.filters index 705fcf6348..3bb24304be 100644 --- a/Fwk/VizFwk/Tests/LibGeometry_UnitTests/LibGeometry_UnitTests.vcxproj.filters +++ b/Fwk/VizFwk/Tests/LibGeometry_UnitTests/LibGeometry_UnitTests.vcxproj.filters @@ -21,6 +21,7 @@ + diff --git a/Fwk/VizFwk/Tests/LibGeometry_UnitTests/cvfPrimitiveTests-Test.cpp b/Fwk/VizFwk/Tests/LibGeometry_UnitTests/cvfPrimitiveTests-Test.cpp new file mode 100644 index 0000000000..313285b108 --- /dev/null +++ b/Fwk/VizFwk/Tests/LibGeometry_UnitTests/cvfPrimitiveTests-Test.cpp @@ -0,0 +1,90 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cvfBase.h" +#include "cvfPrimitiveTests.h" + +#include "gtest/gtest.h" + +using namespace cvf; + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(PrimitiveTestsTest, intersectLines) +{ + { + Vec2d p1(0, 0); Vec2d p2(2, 0); + Vec2d p3(1, -1); Vec2d p4(1, 1); + Vec2d isect(0, 0); + EXPECT_TRUE(PrimitiveTests::intersectLines(p1, p2, p3, p4, &isect)); + EXPECT_DOUBLE_EQ(1, isect.x()); + EXPECT_DOUBLE_EQ(0, isect.y()); + } + + { + Vec2d p1(0, 0); Vec2d p2(2, 0); + Vec2d p3(1, 2); Vec2d p4(1, 1); + Vec2d isect(0, 0); + EXPECT_TRUE(PrimitiveTests::intersectLines(p1, p2, p3, p4, &isect)); + EXPECT_DOUBLE_EQ(1, isect.x()); + EXPECT_DOUBLE_EQ(0, isect.y()); + } + + // Incident + { + Vec2d p1(1, 0); Vec2d p2(3, 0); + Vec2d p3(2, 0); Vec2d p4(4, 0); + Vec2d isect(0, 0); + EXPECT_TRUE(PrimitiveTests::intersectLines(p1, p2, p3, p4, &isect)); + EXPECT_DOUBLE_EQ(2, isect.x()); + EXPECT_DOUBLE_EQ(0, isect.y()); + } + + // Parallell + { + Vec2d p1(0, 0); Vec2d p2(2, 0); + Vec2d p3(0, 2); Vec2d p4(2, 2); + Vec2d isect(0, 0); + EXPECT_FALSE(PrimitiveTests::intersectLines(p1, p2, p3, p4, &isect)); + EXPECT_DOUBLE_EQ(0, isect.x()); + EXPECT_DOUBLE_EQ(0, isect.y()); + } +} + diff --git a/Fwk/VizFwk/Tests/LibViewing_UnitTests/cvfModelBasicList-Test.cpp b/Fwk/VizFwk/Tests/LibViewing_UnitTests/cvfModelBasicList-Test.cpp index 9fe95c1504..9fe362f5f5 100644 --- a/Fwk/VizFwk/Tests/LibViewing_UnitTests/cvfModelBasicList-Test.cpp +++ b/Fwk/VizFwk/Tests/LibViewing_UnitTests/cvfModelBasicList-Test.cpp @@ -128,6 +128,51 @@ TEST(ModelBasicListDeathTest, IllegalIndexing) } #endif + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(ModelBasicListTest, shrinkPartCount) +{ + ref p1 = new Part; + ref p2 = new Part; + ref p3 = new Part; + + { + ref myModel = new ModelBasicList; + myModel->addPart(p1.p()); + myModel->addPart(p2.p()); + myModel->addPart(p3.p()); + ASSERT_EQ(3, myModel->partCount()); + EXPECT_EQ(2, p1->refCount()); + EXPECT_EQ(2, p2->refCount()); + EXPECT_EQ(2, p3->refCount()); + + myModel->shrinkPartCount(3); + ASSERT_EQ(3, myModel->partCount()); + EXPECT_EQ(2, p1->refCount()); + EXPECT_EQ(2, p2->refCount()); + EXPECT_EQ(2, p3->refCount()); + + myModel->shrinkPartCount(2); + ASSERT_EQ(2, myModel->partCount()); + EXPECT_EQ(2, p1->refCount()); + EXPECT_EQ(2, p2->refCount()); + EXPECT_EQ(1, p3->refCount()); + + myModel->shrinkPartCount(0); + ASSERT_EQ(0, myModel->partCount()); + EXPECT_EQ(1, p1->refCount()); + EXPECT_EQ(1, p2->refCount()); + EXPECT_EQ(1, p3->refCount()); + } + + EXPECT_EQ(1, p1->refCount()); + EXPECT_EQ(1, p2->refCount()); + EXPECT_EQ(1, p3->refCount()); +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/VizFwk/Tests/SnippetsBasis/snipVertexColoring.cpp b/Fwk/VizFwk/Tests/SnippetsBasis/snipVertexColoring.cpp index 74a0a13171..51d4c2ffb3 100644 --- a/Fwk/VizFwk/Tests/SnippetsBasis/snipVertexColoring.cpp +++ b/Fwk/VizFwk/Tests/SnippetsBasis/snipVertexColoring.cpp @@ -47,6 +47,16 @@ namespace snip { + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VertexColoring::VertexColoring() +: m_useShaders(false) +{ +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -54,20 +64,37 @@ bool VertexColoring::onInitialize() { ref myModel = new ModelBasicList; - // Create the effect + // Create the fixed function effect { - m_effect = new Effect; + m_fixedFuncEffect = new Effect; ref mat = new RenderStateMaterial_FF(Color3::BLUE); mat->enableColorMaterial(true); - m_effect->setRenderState(mat.p()); + m_fixedFuncEffect->setRenderState(mat.p()); ref lighting = new RenderStateLighting_FF; - m_effect->setRenderState(lighting.p()); + m_fixedFuncEffect->setRenderState(lighting.p()); + } + + // Create effect with shader program + { + m_shaderEffect = new Effect; + + ShaderProgramGenerator gen("PerVertexColor", ShaderSourceProvider::instance()); + gen.addVertexCode(ShaderSourceRepository::vs_Standard); + gen.addFragmentCode(ShaderSourceRepository::src_VaryingColorGlobalAlpha); + gen.addFragmentCode(ShaderSourceRepository::light_SimpleHeadlight); + gen.addFragmentCode(ShaderSourceRepository::fs_Standard); + m_shaderProg = gen.generate(); + m_shaderProg->setDefaultUniform(new cvf::UniformFloat("u_alpha", 1.0f)); + + m_shaderEffect->setShaderProgram(m_shaderProg.p()); } - // "Normal" geometry + ref effectToUse = m_useShaders ? m_shaderEffect : m_fixedFuncEffect; + + // Lower left: "Normal" geometry { GeometryBuilderDrawableGeo builder; GeometryUtils::createBox(Vec3f(0,0,0), 2.0, 2.0, 2.0, &builder); @@ -76,12 +103,13 @@ bool VertexColoring::onInitialize() ref part = new Part; part->setDrawable(geo.p()); - part->setEffect(m_effect.p()); + part->setEffect(effectToUse.p()); myModel->addPart(part.p()); } - // Geometry with per vertex colors + // Lower right: Geometry with per vertex colors + // Results in one color per face of the cube { GeometryBuilderDrawableGeo builder; GeometryUtils::createBox(Vec3f(3,0,0), 2.0, 2.0, 2.0, &builder); @@ -114,12 +142,12 @@ bool VertexColoring::onInitialize() ref part = new Part; part->setDrawable(geo.p()); - part->setEffect(m_effect.p()); + part->setEffect(effectToUse.p()); myModel->addPart(part.p()); } - // Geometry with per vertex colors (using ScalarToColorMapper) + // Upper right: Geometry with per vertex colors (using ScalarToColorMapper) { BoxGenerator gen; gen.setMinMax(Vec3d(2,-1,2), Vec3d(4, 1, 4)); @@ -159,12 +187,12 @@ bool VertexColoring::onInitialize() ref part = new Part; part->setDrawable(geo.p()); - part->setEffect(m_effect.p()); + part->setEffect(effectToUse.p()); myModel->addPart(part.p()); } - // Geometry without normals + // Upper left: Geometry without normals { GeometryBuilderDrawableGeo builder; GeometryUtils::createBox(Vec3f(0,0,3), 2.0, 2.0, 2.0, &builder); @@ -173,7 +201,7 @@ bool VertexColoring::onInitialize() ref part = new Part; part->setDrawable(geo.p()); - part->setEffect(m_effect.p()); + part->setEffect(effectToUse.p()); myModel->addPart(part.p()); } @@ -233,11 +261,24 @@ void VertexColoring::onKeyPressEvent(KeyEvent* keyEvent) Key key = keyEvent->key(); char character = keyEvent->character(); + if (key == Key_S || key == Key_F) + { + m_useShaders = (key == Key_S) ? true : false; + + Collection partCollection; + m_renderSequence->firstRendering()->scene()->model(0)->allParts(&partCollection); + for (size_t i = 0; i < partCollection.size(); i++) + { + ref part = partCollection[i]; + part->setEffect(m_useShaders ? m_shaderEffect.p() : m_fixedFuncEffect.p()); + } + } + if (key == Key_L) { bool lightingOn = (character == 'l') ? true : false; - RenderStateLighting_FF* rsLighting = dynamic_cast(m_effect->renderStateOfType(RenderState::LIGHTING_FF)); + RenderStateLighting_FF* rsLighting = dynamic_cast(m_fixedFuncEffect->renderStateOfType(RenderState::LIGHTING_FF)); rsLighting->enable(lightingOn); } @@ -245,7 +286,7 @@ void VertexColoring::onKeyPressEvent(KeyEvent* keyEvent) { bool colorMaterialOn = (character == 'c') ? true : false; - RenderStateMaterial_FF* rsMaterial = dynamic_cast(m_effect->renderStateOfType(RenderState::MATERIAL_FF)); + RenderStateMaterial_FF* rsMaterial = dynamic_cast(m_fixedFuncEffect->renderStateOfType(RenderState::MATERIAL_FF)); rsMaterial->enableColorMaterial(colorMaterialOn); } @@ -259,8 +300,10 @@ void VertexColoring::onKeyPressEvent(KeyEvent* keyEvent) std::vector VertexColoring::helpText() const { std::vector help; - help.push_back(String("l/L - to toggle lighting on/off")); - help.push_back(String("c/C - to toggle color material on/off")); + help.push_back("s - to use a shader program for rendering"); + help.push_back("f - to use fixed function pipeline for rendering"); + help.push_back("l/L - to toggle lighting on/off (in fixed function)"); + help.push_back("c/C - to toggle color material on/off (in fixed function)"); return help; diff --git a/Fwk/VizFwk/Tests/SnippetsBasis/snipVertexColoring.h b/Fwk/VizFwk/Tests/SnippetsBasis/snipVertexColoring.h index 12fd16b1df..7e310d59f7 100644 --- a/Fwk/VizFwk/Tests/SnippetsBasis/snipVertexColoring.h +++ b/Fwk/VizFwk/Tests/SnippetsBasis/snipVertexColoring.h @@ -55,6 +55,7 @@ class VertexColoring : public TestSnippet CVFU_DECLARE_SNIPPET("Vertex Coloring"); public: + VertexColoring(); virtual bool onInitialize(); virtual void onKeyPressEvent(KeyEvent* keyEvent); @@ -64,7 +65,10 @@ class VertexColoring : public TestSnippet void addEdgesRendering(); private: - ref m_effect; + bool m_useShaders; + ref m_shaderProg; + ref m_fixedFuncEffect; + ref m_shaderEffect; }; } From 48d6986954de52e613f2cba5b2f638c8bfb07b3e Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 11 Apr 2014 11:29:31 +0200 Subject: [PATCH 024/130] Added define used to allow non-threadsafe reference counter --- CMakeLists.txt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 494da32e0d..f551c8beb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,8 +93,15 @@ include (${QT_USE_FILE}) find_package( OpenGL ) ################################################################################ -# CeeViz +# Vizualization Framework ################################################################################ + +# Allow use of non-threadsafe reference counter in cvf::Object on systems with no atomics support +option(RESINSIGHT_WORKAROUND_ON_SYSTEMS_WITHOUT_ATOMICS "Allow use of non-threadsafe reference counter on systems with no atomics support" OFF) +if (RESINSIGHT_WORKAROUND_ON_SYSTEMS_WITHOUT_ATOMICS) + add_definitions(-DCVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS) +endif() + add_subdirectory(${VIZ_MODULES_FOLDER_NAME}/LibCore) add_subdirectory(${VIZ_MODULES_FOLDER_NAME}/LibGeometry) add_subdirectory(${VIZ_MODULES_FOLDER_NAME}/LibRender) @@ -111,7 +118,7 @@ include_directories( ################################################################################ -# Ceetron Application Framework +# Application Framework ################################################################################ add_subdirectory(Fwk/AppFwk/cafProjectDataModel) From 3e8a206f13c5686ef6e81b2978ae34a9c0280e6e Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 07:30:00 +0100 Subject: [PATCH 025/130] Moved mock model identicators to RimDefines --- ApplicationCode/Application/RiaApplication.cpp | 6 +++--- ApplicationCode/ProjectDataModel/RimDefines.h | 9 ++++++++- ApplicationCode/ProjectDataModel/RimResultCase.cpp | 6 +++--- ApplicationCode/UserInterface/RiuMainWindow.cpp | 6 +++--- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ApplicationCode/Application/RiaApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp index f10595a388..9ff31cc740 100644 --- a/ApplicationCode/Application/RiaApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -699,7 +699,7 @@ bool RiaApplication::openInputEclipseCaseFromFileNames(const QStringList& fileNa //-------------------------------------------------------------------------------------------------- void RiaApplication::createMockModel() { - openEclipseCase("Result Mock Debug Model Simple", "Result Mock Debug Model Simple"); + openEclipseCase(RimDefines::mockModelBasic(), RimDefines::mockModelBasic()); } //-------------------------------------------------------------------------------------------------- @@ -707,7 +707,7 @@ void RiaApplication::createMockModel() //-------------------------------------------------------------------------------------------------- void RiaApplication::createResultsMockModel() { - openEclipseCase("Result Mock Debug Model With Results", "Result Mock Debug Model With Results"); + openEclipseCase(RimDefines::mockModelBasicWithResults(), RimDefines::mockModelBasicWithResults()); } @@ -716,7 +716,7 @@ void RiaApplication::createResultsMockModel() //-------------------------------------------------------------------------------------------------- void RiaApplication::createLargeResultsMockModel() { - openEclipseCase("Result Mock Debug Model Large With Results", "Result Mock Debug Model Large With Results"); + openEclipseCase(RimDefines::mockModelLargeWithResults(), RimDefines::mockModelLargeWithResults()); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimDefines.h b/ApplicationCode/ProjectDataModel/RimDefines.h index 95313686a3..cfb31f48ad 100644 --- a/ApplicationCode/ProjectDataModel/RimDefines.h +++ b/ApplicationCode/ProjectDataModel/RimDefines.h @@ -41,7 +41,14 @@ class RimDefines static QString undefinedResultName() { return "None"; } static QString undefinedGridFaultName() { return "Undefined grid faults"; } - static QString combinedTransmissibilityResultName() { return "TRANSXYZ"; } + + + // Mock model text identifiers + static QString mockModelBasic() { return "Result Mock Debug Model Simple"; } + static QString mockModelBasicWithResults() { return "Result Mock Debug Model With Results"; } + static QString mockModelLargeWithResults() { return "Result Mock Debug Model Large With Results"; } + static QString mockModelBasicInputCase() { return "Input Mock Debug Model Simple"; } + }; diff --git a/ApplicationCode/ProjectDataModel/RimResultCase.cpp b/ApplicationCode/ProjectDataModel/RimResultCase.cpp index 4e9157ac22..558245c5f6 100644 --- a/ApplicationCode/ProjectDataModel/RimResultCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultCase.cpp @@ -199,7 +199,7 @@ cvf::ref RimResultCase::createMockModel(QString modelName) cvf::ref mockFileInterface = new RifReaderMockModel; cvf::ref reservoir = new RigCaseData; - if (modelName == "Result Mock Debug Model Simple") + if (modelName == RimDefines::mockModelBasic()) { // Create the mock file interface and and RigSerervoir and set them up. mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(20, 20, 20)); @@ -221,7 +221,7 @@ cvf::ref RimResultCase::createMockModel(QString modelName) //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); } } - else if (modelName == "Result Mock Debug Model With Results") + else if (modelName == RimDefines::mockModelBasicWithResults()) { mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(-20, -20, -20)); mockFileInterface->setGridPointDimensions(cvf::Vec3st(5, 10, 20)); @@ -234,7 +234,7 @@ cvf::ref RimResultCase::createMockModel(QString modelName) cvf::Vec3d& tmp = reservoir->mainGrid()->nodes()[1]; tmp += cvf::Vec3d(1, 0, 0); } - else if (modelName =="Result Mock Debug Model Large With Results") + else if (modelName == RimDefines::mockModelLargeWithResults()) { double startX = 0; double startY = 0; diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index 930a0c337c..dd1e7090c2 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -1446,9 +1446,9 @@ void RiuMainWindow::slotOpenMultipleCases() if (1) { - gridFileNames += "Result Mock Debug Model With Results"; - gridFileNames += "Result Mock Debug Model With Results"; - gridFileNames += "Result Mock Debug Model With Results"; + gridFileNames += RimDefines::mockModelBasicWithResults(); + gridFileNames += RimDefines::mockModelBasicWithResults(); + gridFileNames += RimDefines::mockModelBasicWithResults(); } else { From 00cc1a88a5b3d5f85c43749d2ce29869798146ce Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 10:30:11 +0100 Subject: [PATCH 026/130] Added serialization of pdm objects using QSettings --- Fwk/AppFwk/cafUserInterface/CMakeLists.txt | 2 + .../cafUserInterface/cafPdmSettings.cpp | 116 ++++++++++++++++++ Fwk/AppFwk/cafUserInterface/cafPdmSettings.h | 55 +++++++++ 3 files changed, 173 insertions(+) create mode 100644 Fwk/AppFwk/cafUserInterface/cafPdmSettings.cpp create mode 100644 Fwk/AppFwk/cafUserInterface/cafPdmSettings.h diff --git a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt index 69496b3ffe..b09a2f49a1 100644 --- a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt +++ b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt @@ -11,6 +11,7 @@ set( QOBJECT_HEADERS cafUiTreeModelPdm.h cafUiProcess.h + cafPdmSettings.h cafPdmUiLineEditor.h cafPdmUiCheckBoxEditor.h cafPdmUiComboBoxEditor.h @@ -38,6 +39,7 @@ endif() add_library( ${PROJECT_NAME} cafAboutDialog.cpp cafAboutDialog.h + cafPdmSettings.cpp cafPdmUiCheckBoxEditor.cpp cafPdmUiCheckBoxEditor.h cafPdmUiColorEditor.cpp diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmSettings.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmSettings.cpp new file mode 100644 index 0000000000..a8e3a3ba5c --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmSettings.cpp @@ -0,0 +1,116 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmSettings.h" +#include "cafPdmField.h" + +#include + + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Settings::readFieldsFromApplicationStore(caf::PdmObject* object) +{ + // Qt doc : + // + // Constructs a QSettings object for accessing settings of the application and organization + // set previously with a call to QCoreApplication::setOrganizationName(), + // QCoreApplication::setOrganizationDomain(), and QCoreApplication::setApplicationName(). + QSettings settings; + + QString prefix = object->classKeyword(); + if (!prefix.isEmpty()) + { + prefix += "/"; + } + + std::vector fields; + object->fields(fields); + size_t i; + for (i = 0; i < fields.size(); i++) + { + caf::PdmFieldHandle* fieldHandle = fields[i]; + + QString keywordWithPrefix = prefix + fieldHandle->keyword(); + if (settings.contains(keywordWithPrefix)) + { + QVariant val = settings.value(keywordWithPrefix); + fieldHandle->setValueFromUi(val); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Settings::writeFieldsToApplicationStore(caf::PdmObject* object) +{ + assert(object); + + // Qt doc : + // + // Constructs a QSettings object for accessing settings of the application and organization + // set previously with a call to QCoreApplication::setOrganizationName(), + // QCoreApplication::setOrganizationDomain(), and QCoreApplication::setApplicationName(). + QSettings settings; + + QString prefix = object->classKeyword(); + if (!prefix.isEmpty()) + { + prefix += "/"; + } + + std::vector fields; + object->fields(fields); + + size_t i; + for (i = 0; i < fields.size(); i++) + { + caf::PdmFieldHandle* fieldHandle = fields[i]; + + QString keywordWithPrefix = prefix + fieldHandle->keyword(); + settings.setValue(keywordWithPrefix, fieldHandle->uiValue()); + } +} + + +} // namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmSettings.h b/Fwk/AppFwk/cafUserInterface/cafPdmSettings.h new file mode 100644 index 0000000000..2342eacd71 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmSettings.h @@ -0,0 +1,55 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include + +namespace caf +{ + + class PdmObject; + +class Settings +{ +public: + static void readFieldsFromApplicationStore(caf::PdmObject* object); + static void writeFieldsToApplicationStore(caf::PdmObject* object); +}; + + +} // end namespace caf From 5961b267b62f5285f5176335e0a37fb41419fa26 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 10:30:58 +0100 Subject: [PATCH 027/130] Added mock model settings --- .../ProjectDataModel/CMakeLists_files.cmake | 2 + .../ProjectDataModel/RimMockModelSettings.cpp | 73 +++++++++++++++++++ .../ProjectDataModel/RimMockModelSettings.h | 52 +++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp create mode 100644 ApplicationCode/ProjectDataModel/RimMockModelSettings.h diff --git a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake index d1eba17c50..4e0d185f37 100644 --- a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake @@ -46,6 +46,7 @@ ${CEE_CURRENT_LIST_DIR}RimCommandObject.h ${CEE_CURRENT_LIST_DIR}RimTools.h ${CEE_CURRENT_LIST_DIR}RimFault.h ${CEE_CURRENT_LIST_DIR}RimFaultCollection.h +${CEE_CURRENT_LIST_DIR}RimMockModelSettings.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -90,6 +91,7 @@ ${CEE_CURRENT_LIST_DIR}RimCommandObject.cpp ${CEE_CURRENT_LIST_DIR}RimTools.cpp ${CEE_CURRENT_LIST_DIR}RimFault.cpp ${CEE_CURRENT_LIST_DIR}RimFaultCollection.cpp +${CEE_CURRENT_LIST_DIR}RimMockModelSettings.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp b/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp new file mode 100644 index 0000000000..3e032f107a --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimMockModelSettings.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 "RiaStdInclude.h" + + +#include "RimMockModelSettings.h" + + + + +CAF_PDM_SOURCE_INIT(RimMockModelSettings, "MockModelSettings"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMockModelSettings::RimMockModelSettings() +{ + CAF_PDM_InitObject("Mock Model Settings", "", "", ""); + + CAF_PDM_InitField(&cellCountX, "CellCountX", quint64(100), "Cell Count X", "", "", ""); + CAF_PDM_InitField(&cellCountY, "CellCountY", quint64(100), "Cell Count Y", "", "", ""); + CAF_PDM_InitField(&cellCountZ, "CellCountZ", quint64(100), "Cell Count Z", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&totalCellCount, "TotalCellCount", "Total Cell Count", "", "", ""); + totalCellCount.setUiReadOnly(true); + + CAF_PDM_InitField(&resultCount, "ResultCount", quint64(3), "Result Count", "", "", ""); + CAF_PDM_InitField(&timeStepCount, "TimeStepCount", quint64(10), "Time Step Count", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMockModelSettings::~RimMockModelSettings() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMockModelSettings::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + totalCellCount = cellCountX * cellCountY * cellCountZ; + totalCellCount.updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMockModelSettings::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + caf::PdmUiGroup* gridSizeGroup = uiOrdering.addNewGroup("Grid size"); + gridSizeGroup->add(&cellCountX); + gridSizeGroup->add(&cellCountY); + gridSizeGroup->add(&cellCountZ); + gridSizeGroup->add(&totalCellCount); +} diff --git a/ApplicationCode/ProjectDataModel/RimMockModelSettings.h b/ApplicationCode/ProjectDataModel/RimMockModelSettings.h new file mode 100644 index 0000000000..64d1beac66 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimMockModelSettings.h @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPointer.h" + + +//================================================================================================== +/// +/// +//================================================================================================== +class RimMockModelSettings : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + + RimMockModelSettings(); + virtual ~RimMockModelSettings(); + + caf::PdmField cellCountX; + caf::PdmField cellCountY; + caf::PdmField cellCountZ; + + caf::PdmField totalCellCount; + + caf::PdmField resultCount; + caf::PdmField timeStepCount; + + + virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); + + virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ); + +}; From 7ffe48bff9e7cd7919ecab686d03c17553199503 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 10:31:46 +0100 Subject: [PATCH 028/130] Added flag to control adding of well data --- .../ReservoirDataModel/RigReservoirBuilderMock.cpp | 11 ++++++++++- .../ReservoirDataModel/RigReservoirBuilderMock.h | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp index 0905772400..116dc4e8d3 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp @@ -34,6 +34,7 @@ RigReservoirBuilderMock::RigReservoirBuilderMock() m_resultCount = 0; m_timeStepCount = 0; m_gridPointDimensions = cvf::Vec3st::ZERO; + m_enableWellData = true; } //-------------------------------------------------------------------------------------------------- @@ -246,7 +247,10 @@ void RigReservoirBuilderMock::populateReservoir(RigCaseData* eclipseCase) eclipseCase->mainGrid()->setGridPointDimensions(m_gridPointDimensions); - addWellData(eclipseCase, eclipseCase->mainGrid()); + if (m_enableWellData) + { + addWellData(eclipseCase, eclipseCase->mainGrid()); + } addFaults(eclipseCase); @@ -521,3 +525,8 @@ void RigReservoirBuilderMock::addFaults(RigCaseData* eclipseCase) grid->setFaults(faults); } +void RigReservoirBuilderMock::enableWellData(bool enableWellData) +{ + m_enableWellData = false; +} + diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h index 619fb0069a..7076027264 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h @@ -48,6 +48,7 @@ class RigReservoirBuilderMock void setWorldCoordinates(cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate); void setGridPointDimensions(const cvf::Vec3st& gridPointDimensions); void setResultInfo(size_t resultCount, size_t timeStepCount); + void enableWellData(bool enableWellData); size_t resultCount() const { return m_resultCount; } size_t timeStepCount() const { return m_timeStepCount; } @@ -91,6 +92,7 @@ class RigReservoirBuilderMock cvf::Vec3st m_gridPointDimensions; size_t m_resultCount; size_t m_timeStepCount; + bool m_enableWellData; std::vector m_localGridRefinements; }; From ae9f72912eb2152c2b6adff6f46722c656a7a03b Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 10:32:24 +0100 Subject: [PATCH 029/130] Added customized mock model to user interface --- .../Application/RiaApplication.cpp | 11 +++++++- ApplicationCode/Application/RiaApplication.h | 1 + .../FileInterface/RifReaderMockModel.cpp | 8 ++++++ .../FileInterface/RifReaderMockModel.h | 1 + ApplicationCode/ProjectDataModel/RimDefines.h | 1 + .../ProjectDataModel/RimInputCase.cpp | 6 ++--- .../ProjectDataModel/RimResultCase.cpp | 27 +++++++++++++++++++ .../UserInterface/RiuMainWindow.cpp | 15 ++++++++--- ApplicationCode/UserInterface/RiuMainWindow.h | 2 ++ 9 files changed, 64 insertions(+), 8 deletions(-) diff --git a/ApplicationCode/Application/RiaApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp index 9ff31cc740..d029af322f 100644 --- a/ApplicationCode/Application/RiaApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -719,12 +719,21 @@ void RiaApplication::createLargeResultsMockModel() openEclipseCase(RimDefines::mockModelLargeWithResults(), RimDefines::mockModelLargeWithResults()); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaApplication::createMockModelCustomized() +{ + openEclipseCase(RimDefines::mockModelCustomized(), RimDefines::mockModelCustomized()); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiaApplication::createInputMockModel() { - openInputEclipseCaseFromFileNames(QStringList("Input Mock Debug Model Simple")); + openInputEclipseCaseFromFileNames(QStringList(RimDefines::mockModelBasicInputCase())); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Application/RiaApplication.h b/ApplicationCode/Application/RiaApplication.h index 5688087195..f026d613b6 100644 --- a/ApplicationCode/Application/RiaApplication.h +++ b/ApplicationCode/Application/RiaApplication.h @@ -81,6 +81,7 @@ class RiaApplication : public QApplication void createMockModel(); void createResultsMockModel(); void createLargeResultsMockModel(); + void createMockModelCustomized(); void createInputMockModel(); QString defaultFileDialogDirectory(const QString& dialogName); diff --git a/ApplicationCode/FileInterface/RifReaderMockModel.cpp b/ApplicationCode/FileInterface/RifReaderMockModel.cpp index f03a79e40f..64507ebc8d 100644 --- a/ApplicationCode/FileInterface/RifReaderMockModel.cpp +++ b/ApplicationCode/FileInterface/RifReaderMockModel.cpp @@ -175,3 +175,11 @@ void RifReaderMockModel::populateReservoir(RigCaseData* eclipseCase) m_reservoirBuilder.populateReservoir(eclipseCase); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderMockModel::enableWellData(bool enableWellData) +{ + m_reservoirBuilder.enableWellData(enableWellData); +} + diff --git a/ApplicationCode/FileInterface/RifReaderMockModel.h b/ApplicationCode/FileInterface/RifReaderMockModel.h index 0237381bbe..3acd5a7c7b 100644 --- a/ApplicationCode/FileInterface/RifReaderMockModel.h +++ b/ApplicationCode/FileInterface/RifReaderMockModel.h @@ -30,6 +30,7 @@ class RifReaderMockModel : public RifReaderInterface void setWorldCoordinates(cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate); void setGridPointDimensions(const cvf::Vec3st& gridPointDimensions); void setResultInfo(size_t resultCount, size_t timeStepCount); + void enableWellData(bool enableWellData); void addLocalGridRefinement(const cvf::Vec3st& minCellPosition, const cvf::Vec3st& maxCellPosition, const cvf::Vec3st& singleCellRefinementFactors); diff --git a/ApplicationCode/ProjectDataModel/RimDefines.h b/ApplicationCode/ProjectDataModel/RimDefines.h index cfb31f48ad..0dd82175f1 100644 --- a/ApplicationCode/ProjectDataModel/RimDefines.h +++ b/ApplicationCode/ProjectDataModel/RimDefines.h @@ -48,6 +48,7 @@ class RimDefines static QString mockModelBasic() { return "Result Mock Debug Model Simple"; } static QString mockModelBasicWithResults() { return "Result Mock Debug Model With Results"; } static QString mockModelLargeWithResults() { return "Result Mock Debug Model Large With Results"; } + static QString mockModelCustomized() { return "Result Mock Debug Model Customized"; } static QString mockModelBasicInputCase() { return "Input Mock Debug Model Simple"; } }; diff --git a/ApplicationCode/ProjectDataModel/RimInputCase.cpp b/ApplicationCode/ProjectDataModel/RimInputCase.cpp index ddfa4876fe..e9ab1a607f 100644 --- a/ApplicationCode/ProjectDataModel/RimInputCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimInputCase.cpp @@ -77,7 +77,7 @@ RimInputCase::~RimInputCase() //-------------------------------------------------------------------------------------------------- void RimInputCase::openDataFileSet(const QStringList& fileNames) { - if (fileNames.contains("Input Mock Debug Model Simple")) + if (fileNames.contains(RimDefines::mockModelBasicInputCase())) { cvf::ref readerInterface = this->createMockModel(fileNames[0]); results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); @@ -184,7 +184,7 @@ bool RimInputCase::openEclipseGridFile() { cvf::ref readerInterface; - if (m_gridFileName().contains("Input Mock Debug Model Simple")) + if (m_gridFileName().contains(RimDefines::mockModelBasicInputCase())) { readerInterface = this->createMockModel(this->m_gridFileName()); } @@ -377,7 +377,7 @@ cvf::ref RimInputCase::createMockModel(QString modelName) cvf::ref reservoir = new RigCaseData; cvf::ref mockFileInterface = new RifReaderMockModel; - if (modelName == "Input Mock Debug Model Simple") + if (modelName == RimDefines::mockModelBasicInputCase()) { m_gridFileName = modelName; diff --git a/ApplicationCode/ProjectDataModel/RimResultCase.cpp b/ApplicationCode/ProjectDataModel/RimResultCase.cpp index 558245c5f6..d13fddbc2f 100644 --- a/ApplicationCode/ProjectDataModel/RimResultCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultCase.cpp @@ -45,6 +45,7 @@ #include "RimOilField.h" #include "RimAnalysisModels.h" #include "RiaPreferences.h" +#include "RimMockModelSettings.h" CAF_PDM_SOURCE_INIT(RimResultCase, "EclipseCase"); //-------------------------------------------------------------------------------------------------- @@ -262,6 +263,32 @@ cvf::ref RimResultCase::createMockModel(QString modelName) mockFileInterface->open("", reservoir.p()); } + else if (modelName == RimDefines::mockModelCustomized()) + { + RimMockModelSettings rimMockModelSettings; + + //caf::Settings::readFieldsFromApplicationStore(&rimMockModelSettings); + + double startX = 0; + double startY = 0; + double startZ = 0; + + double widthX = 6000; + double widthY = 12000; + double widthZ = 500; + + // Test code to simulate UTM coordinates + double offsetX = 400000; + double offsetY = 6000000; + double offsetZ = 0; + + mockFileInterface->setWorldCoordinates(cvf::Vec3d(startX + offsetX, startY + offsetY, startZ + offsetZ), cvf::Vec3d(startX + widthX + offsetX, startY + widthY + offsetY, startZ + widthZ + offsetZ)); + mockFileInterface->setGridPointDimensions(cvf::Vec3st(rimMockModelSettings.cellCountX, rimMockModelSettings.cellCountX, rimMockModelSettings.cellCountX)); + mockFileInterface->setResultInfo(rimMockModelSettings.resultCount, rimMockModelSettings.timeStepCount); + mockFileInterface->enableWellData(false); + + mockFileInterface->open("", reservoir.p()); + } this->setReservoirData( reservoir.p() ); diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index dd1e7090c2..2e39767fc2 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -199,6 +199,7 @@ void RiuMainWindow::createActions() m_mockModelAction = new QAction("&Mock Model", this); m_mockResultsModelAction = new QAction("Mock Model With &Results", this); m_mockLargeResultsModelAction = new QAction("Large Mock Model", this); + m_mockModelCustomizedAction = new QAction("Customized Mock Model", this); m_mockInputModelAction = new QAction("Input Mock Model", this); m_snapshotToFile = new QAction(QIcon(":/SnapShotSave.png"), "Snapshot To File", this); @@ -226,6 +227,7 @@ void RiuMainWindow::createActions() connect(m_mockModelAction, SIGNAL(triggered()), SLOT(slotMockModel())); connect(m_mockResultsModelAction, SIGNAL(triggered()), SLOT(slotMockResultsModel())); connect(m_mockLargeResultsModelAction, SIGNAL(triggered()), SLOT(slotMockLargeResultsModel())); + connect(m_mockModelCustomizedAction, SIGNAL(triggered()), SLOT(slotMockModelCustomized())); connect(m_mockInputModelAction, SIGNAL(triggered()), SLOT(slotInputMockModel())); connect(m_snapshotToFile, SIGNAL(triggered()), SLOT(slotSnapshotToFile())); @@ -386,6 +388,7 @@ void RiuMainWindow::createMenus() testMenu->addAction(m_mockModelAction); testMenu->addAction(m_mockResultsModelAction); testMenu->addAction(m_mockLargeResultsModelAction); + testMenu->addAction(m_mockModelCustomizedAction); testMenu->addAction(m_mockInputModelAction); testMenu->addSeparator(); testMenu->addAction(m_createCommandObject); @@ -845,8 +848,6 @@ void RiuMainWindow::slotMockModel() { RiaApplication* app = RiaApplication::instance(); app->createMockModel(); - - //m_mainViewer->setDefaultView(); } //-------------------------------------------------------------------------------------------------- @@ -856,8 +857,6 @@ void RiuMainWindow::slotMockResultsModel() { RiaApplication* app = RiaApplication::instance(); app->createResultsMockModel(); - - //m_mainViewer->setDefaultView(); } @@ -870,6 +869,14 @@ void RiuMainWindow::slotMockLargeResultsModel() app->createLargeResultsMockModel(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMainWindow::slotMockModelCustomized() +{ + RiaApplication* app = RiaApplication::instance(); + app->createMockModelCustomized(); +} //-------------------------------------------------------------------------------------------------- /// diff --git a/ApplicationCode/UserInterface/RiuMainWindow.h b/ApplicationCode/UserInterface/RiuMainWindow.h index 2b92f9a7b4..ae3f922af3 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.h +++ b/ApplicationCode/UserInterface/RiuMainWindow.h @@ -154,6 +154,7 @@ class RiuMainWindow : public QMainWindow QAction* m_mockModelAction; QAction* m_mockResultsModelAction; QAction* m_mockLargeResultsModelAction; + QAction* m_mockModelCustomizedAction; QAction* m_mockInputModelAction; QAction* m_snapshotToFile; @@ -243,6 +244,7 @@ private slots: void slotMockModel(); void slotMockResultsModel(); void slotMockLargeResultsModel(); + void slotMockModelCustomized(); void slotInputMockModel(); // Windows slots From c9116070de3420a1443c57473be0bddd023fe47e Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 11:55:34 +0100 Subject: [PATCH 030/130] Added default editor for quint64 --- Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp index 822d2c3185..5bfee7de4f 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp @@ -65,10 +65,11 @@ CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, QString); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, int); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, double); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, float); +CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, quint64); + CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); - CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); From 4300e746749eceee4d121e5d7896a07fdabeba46 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 11:58:49 +0100 Subject: [PATCH 031/130] Added property dialog --- Fwk/AppFwk/cafUserInterface/CMakeLists.txt | 3 + .../cafPdmUiPropertyDialog.cpp | 92 +++++++++++++++++++ .../cafUserInterface/cafPdmUiPropertyDialog.h | 70 ++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.cpp create mode 100644 Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.h diff --git a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt index b09a2f49a1..b210e4a322 100644 --- a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt +++ b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt @@ -25,6 +25,7 @@ set( QOBJECT_HEADERS cafPdmUiColorEditor.h cafPdmUiPropertyView.h + cafPdmUiPropertyDialog.h cafPdmUiTreeView.h cafPdmUiTreeViewModel.h cafPdmUiListView.h @@ -59,6 +60,8 @@ add_library( ${PROJECT_NAME} cafPdmUiListViewEditor.cpp cafPdmUiListViewEditor.h cafPdmUiListView.cpp + cafPdmUiPropertyDialog.cpp + cafPdmUiPropertyDialog.h cafPdmUiPropertyView.cpp cafPdmUiPropertyView.h cafPdmUiPushButtonEditor.cpp diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.cpp new file mode 100644 index 0000000000..277dc3153d --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.cpp @@ -0,0 +1,92 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmUiPropertyDialog.h" + +#include "cafPdmObject.h" +#include "cafPdmUiPropertyView.h" + +#include +#include + +#include + + + +namespace caf { + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiPropertyDialog::PdmUiPropertyDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle) + : QDialog(parent) +{ + assert(object); + + m_pdmObject = object; + m_windowTitle = windowTitle; + + setupUi(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiPropertyDialog::setupUi() +{ + setWindowTitle(m_windowTitle); + + m_pdmUiPropertyView = new caf::PdmUiPropertyView(this); + + QVBoxLayout* dialogLayout = new QVBoxLayout; + setLayout(dialogLayout); + + dialogLayout->addWidget(m_pdmUiPropertyView); + m_pdmUiPropertyView->showProperties(m_pdmObject); + + // Buttons + QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + dialogLayout->addWidget(buttonBox); + + this->resize(400, 200); +} + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.h new file mode 100644 index 0000000000..4c4ca7b797 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.h @@ -0,0 +1,70 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include + +namespace caf +{ + class PdmObject; + class PdmUiPropertyView; + + +//================================================================================================== +// +// +// +//================================================================================================== +class PdmUiPropertyDialog : public QDialog +{ + Q_OBJECT + +public: + PdmUiPropertyDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle); + +private: + void setupUi(); + +private: + QString m_windowTitle; + caf::PdmObject* m_pdmObject; + caf::PdmUiPropertyView* m_pdmUiPropertyView; +}; + + +} // end namespace caf From 6e3860571ecb350320462244760349723f11fc46 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 12:05:06 +0100 Subject: [PATCH 032/130] Improved mock model settings and use caf property dialog --- .../ProjectDataModel/RimMockModelSettings.cpp | 6 +- .../ProjectDataModel/RimResultCase.cpp | 56 ++++++++++++------- 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp b/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp index 3e032f107a..1266629d4e 100644 --- a/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp +++ b/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp @@ -35,7 +35,7 @@ RimMockModelSettings::RimMockModelSettings() CAF_PDM_InitField(&cellCountX, "CellCountX", quint64(100), "Cell Count X", "", "", ""); CAF_PDM_InitField(&cellCountY, "CellCountY", quint64(100), "Cell Count Y", "", "", ""); - CAF_PDM_InitField(&cellCountZ, "CellCountZ", quint64(100), "Cell Count Z", "", "", ""); + CAF_PDM_InitField(&cellCountZ, "CellCountZ", quint64(10), "Cell Count Z", "", "", ""); CAF_PDM_InitFieldNoDefault(&totalCellCount, "TotalCellCount", "Total Cell Count", "", "", ""); totalCellCount.setUiReadOnly(true); @@ -70,4 +70,8 @@ void RimMockModelSettings::defineUiOrdering(QString uiConfigName, caf::PdmUiOrde gridSizeGroup->add(&cellCountY); gridSizeGroup->add(&cellCountZ); gridSizeGroup->add(&totalCellCount); + + caf::PdmUiGroup* resultGroup = uiOrdering.addNewGroup("Results"); + resultGroup->add(&resultCount); + resultGroup->add(&timeStepCount); } diff --git a/ApplicationCode/ProjectDataModel/RimResultCase.cpp b/ApplicationCode/ProjectDataModel/RimResultCase.cpp index d13fddbc2f..a392121b5f 100644 --- a/ApplicationCode/ProjectDataModel/RimResultCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultCase.cpp @@ -17,6 +17,13 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RiaStdInclude.h" + +#include "cafProgressInfo.h" +#include "cafPdmSettings.h" +#include "cafPdmFieldCvfMat4d.h" +#include "cafPdmFieldCvfColor.h" +#include "cafPdmUiPropertyDialog.h" + #include "RimResultCase.h" #include "RigCaseData.h" #include "RifReaderEclipseOutput.h" @@ -24,7 +31,7 @@ #include "RimReservoirView.h" #include "RifReaderMockModel.h" #include "RifReaderEclipseInput.h" -#include "cafProgressInfo.h" + #include "RimProject.h" #include "RifEclipseOutputFileTools.h" #include "RiaApplication.h" @@ -34,8 +41,6 @@ #include "RimReservoirCellResultsCacher.h" #include "RimWellPathCollection.h" -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" #include "RimResultSlot.h" #include "RimCellEdgeResultSlot.h" #include "RimCellRangeFilterCollection.h" @@ -265,29 +270,42 @@ cvf::ref RimResultCase::createMockModel(QString modelName) } else if (modelName == RimDefines::mockModelCustomized()) { + QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); + RimMockModelSettings rimMockModelSettings; + caf::Settings::readFieldsFromApplicationStore(&rimMockModelSettings); - //caf::Settings::readFieldsFromApplicationStore(&rimMockModelSettings); + caf::PdmUiPropertyDialog propertyDialog(NULL, &rimMockModelSettings, "Customize Mock Model"); + if (propertyDialog.exec() == QDialog::Accepted) + { + QApplication::restoreOverrideCursor(); - double startX = 0; - double startY = 0; - double startZ = 0; + caf::Settings::writeFieldsToApplicationStore(&rimMockModelSettings); - double widthX = 6000; - double widthY = 12000; - double widthZ = 500; + double startX = 0; + double startY = 0; + double startZ = 0; - // Test code to simulate UTM coordinates - double offsetX = 400000; - double offsetY = 6000000; - double offsetZ = 0; + double widthX = 6000; + double widthY = 12000; + double widthZ = 500; - mockFileInterface->setWorldCoordinates(cvf::Vec3d(startX + offsetX, startY + offsetY, startZ + offsetZ), cvf::Vec3d(startX + widthX + offsetX, startY + widthY + offsetY, startZ + widthZ + offsetZ)); - mockFileInterface->setGridPointDimensions(cvf::Vec3st(rimMockModelSettings.cellCountX, rimMockModelSettings.cellCountX, rimMockModelSettings.cellCountX)); - mockFileInterface->setResultInfo(rimMockModelSettings.resultCount, rimMockModelSettings.timeStepCount); - mockFileInterface->enableWellData(false); + // Test code to simulate UTM coordinates + double offsetX = 400000; + double offsetY = 6000000; + double offsetZ = 0; - mockFileInterface->open("", reservoir.p()); + mockFileInterface->setWorldCoordinates(cvf::Vec3d(startX + offsetX, startY + offsetY, startZ + offsetZ), cvf::Vec3d(startX + widthX + offsetX, startY + widthY + offsetY, startZ + widthZ + offsetZ)); + mockFileInterface->setGridPointDimensions(cvf::Vec3st(rimMockModelSettings.cellCountX + 1, rimMockModelSettings.cellCountY + 1, rimMockModelSettings.cellCountZ + 1)); + mockFileInterface->setResultInfo(rimMockModelSettings.resultCount, rimMockModelSettings.timeStepCount); + mockFileInterface->enableWellData(false); + + mockFileInterface->open("", reservoir.p()); + } + else + { + QApplication::restoreOverrideCursor(); + } } this->setReservoirData( reservoir.p() ); From 4aeac9197bea6cfe44470ac3d3f05d3afe80068e Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 12:50:39 +0100 Subject: [PATCH 033/130] Use caf property dialog and removed obsolete riuPreferencesDialog --- ApplicationCode/CMakeLists.txt | 2 - .../ProjectDataModel/RimUiTreeView.cpp | 15 ++--- .../UserInterface/RiuMainWindow.cpp | 8 +-- .../UserInterface/RiuPreferencesDialog.cpp | 67 ------------------- .../UserInterface/RiuPreferencesDialog.h | 49 -------------- 5 files changed, 11 insertions(+), 130 deletions(-) delete mode 100644 ApplicationCode/UserInterface/RiuPreferencesDialog.cpp delete mode 100644 ApplicationCode/UserInterface/RiuPreferencesDialog.h diff --git a/ApplicationCode/CMakeLists.txt b/ApplicationCode/CMakeLists.txt index d5fea80758..29c2db248b 100644 --- a/ApplicationCode/CMakeLists.txt +++ b/ApplicationCode/CMakeLists.txt @@ -43,7 +43,6 @@ set( APPLICATION_FILES set( USER_INTERFACE_FILES UserInterface/RiuCursors.cpp UserInterface/RiuMainWindow.cpp - UserInterface/RiuPreferencesDialog.cpp UserInterface/RiuResultInfoPanel.cpp UserInterface/RiuViewer.cpp UserInterface/RiuSimpleHistogramWidget.cpp @@ -98,7 +97,6 @@ set ( QT_MOC_HEADERS ProjectDataModel/RimMimeData.h UserInterface/RiuMainWindow.h - UserInterface/RiuPreferencesDialog.h UserInterface/RiuResultInfoPanel.h UserInterface/RiuViewer.h UserInterface/RiuProcessMonitor.h diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp b/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp index 272c7cca9b..690c0bdfa7 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp +++ b/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp @@ -19,6 +19,9 @@ //#include "RiaStdInclude.h" #include "cafPdmDocument.h" +#include "cafPdmFieldCvfColor.h" +#include "cafPdmFieldCvfMat4d.h" +#include "cafPdmUiPropertyDialog.h" #include #include @@ -37,7 +40,6 @@ #include "RimInputPropertyCollection.h" #include "RimExportInputPropertySettings.h" #include "RiaPreferences.h" -#include "RiuPreferencesDialog.h" #include "RifEclipseInputFileTools.h" #include "RimInputCase.h" #include "RimBinaryExportSettings.h" @@ -59,9 +61,6 @@ #include "RimWellPathCollection.h" #include "RimReservoirCellResultsCacher.h" #include "Rim3dOverlayInfoConfig.h" - -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" #include "RimProject.h" #include "RimOilField.h" #include "RimAnalysisModels.h" @@ -834,8 +833,8 @@ void RimUiTreeView::slotWriteInputProperty() exportSettings.fileName = outputFileName; } - RiuPreferencesDialog preferencesDialog(this, &exportSettings, "Export Eclipse Property to Text File"); - if (preferencesDialog.exec() == QDialog::Accepted) + caf::PdmUiPropertyDialog propertyDialog(this, &exportSettings, "Export Eclipse Property to Text File"); + if (propertyDialog.exec() == QDialog::Accepted) { bool isOk = RifEclipseInputFileTools::writePropertyToTextFile(exportSettings.fileName, inputReservoir->reservoirData(), 0, inputProperty->resultName, exportSettings.eclipseKeyword); if (isOk) @@ -887,8 +886,8 @@ void RimUiTreeView::slotWriteBinaryResultAsInputProperty() exportSettings.fileName = outputFileName; } - RiuPreferencesDialog preferencesDialog(this, &exportSettings, "Export Binary Eclipse Data to Text File"); - if (preferencesDialog.exec() == QDialog::Accepted) + caf::PdmUiPropertyDialog propertyDialog(this, &exportSettings, "Export Binary Eclipse Data to Text File"); + if (propertyDialog.exec() == QDialog::Accepted) { size_t timeStep = resultSlot->reservoirView()->currentTimeStep(); RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultSlot->porosityModel()); diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index 2e39767fc2..103a853f52 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -43,7 +43,6 @@ #include "RiuMultiCaseImportDialog.h" #include "RiaPreferences.h" -#include "RiuPreferencesDialog.h" #include "RigCaseCellResultsData.h" @@ -63,6 +62,7 @@ #include "RimCalcScript.h" #include "RimTools.h" #include "RiaRegressionTest.h" +#include "cafPdmUiPropertyDialog.h" @@ -1223,8 +1223,8 @@ void RiuMainWindow::slotShowPerformanceInfo(bool enable) void RiuMainWindow::slotEditPreferences() { RiaApplication* app = RiaApplication::instance(); - RiuPreferencesDialog preferencesDialog(this, app->preferences(), "Preferences"); - if (preferencesDialog.exec() == QDialog::Accepted) + caf::PdmUiPropertyDialog propertyDialog(this, app->preferences(), "Preferences"); + if (propertyDialog.exec() == QDialog::Accepted) { // Write preferences using QSettings and apply them to the application app->writeFieldsToApplicationStore(app->preferences()); @@ -1772,7 +1772,7 @@ void RiuMainWindow::slotShowRegressionTestDialog() RiaApplication* app = RiaApplication::instance(); app->readFieldsFromApplicationStore(®TestConfig); - RiuPreferencesDialog regressionTestDialog(this, ®TestConfig, "Regression Test"); + caf::PdmUiPropertyDialog regressionTestDialog(this, ®TestConfig, "Regression Test"); if (regressionTestDialog.exec() == QDialog::Accepted) { // Write preferences using QSettings and apply them to the application diff --git a/ApplicationCode/UserInterface/RiuPreferencesDialog.cpp b/ApplicationCode/UserInterface/RiuPreferencesDialog.cpp deleted file mode 100644 index 7a094776c8..0000000000 --- a/ApplicationCode/UserInterface/RiuPreferencesDialog.cpp +++ /dev/null @@ -1,67 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#include "RiaStdInclude.h" -#include "RiuPreferencesDialog.h" - -#include "cafAppEnum.h" -#include "cafPdmObject.h" - -#include "RimUiTreeModelPdm.h" -#include "cafPdmUiPropertyView.h" - - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RiuPreferencesDialog::RiuPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle) - : QDialog(parent) -{ - CVF_ASSERT(object); - - m_pdmObject = object; - m_windowTitle = windowTitle; - - setupUi(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuPreferencesDialog::setupUi() -{ - setWindowTitle(m_windowTitle); - - m_pdmUiPropertyView = new caf::PdmUiPropertyView(this); - - QVBoxLayout* dialogLayout = new QVBoxLayout; - setLayout(dialogLayout); - - dialogLayout->addWidget(m_pdmUiPropertyView); - m_pdmUiPropertyView->showProperties(m_pdmObject); - - // Buttons - QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - dialogLayout->addWidget(buttonBox); - - this->resize(400, 200); -} diff --git a/ApplicationCode/UserInterface/RiuPreferencesDialog.h b/ApplicationCode/UserInterface/RiuPreferencesDialog.h deleted file mode 100644 index 3751e108fb..0000000000 --- a/ApplicationCode/UserInterface/RiuPreferencesDialog.h +++ /dev/null @@ -1,49 +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 - -namespace caf -{ - class PdmObject; - class PdmUiPropertyView; -} - - -//================================================================================================== -// -// -// -//================================================================================================== -class RiuPreferencesDialog : public QDialog -{ - Q_OBJECT - -public: - RiuPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle); - -private: - void setupUi(); - -private: - QString m_windowTitle; - caf::PdmObject* m_pdmObject; - caf::PdmUiPropertyView* m_pdmUiPropertyView; -}; From 60ff9c5a2ba9bb735b3bdec11b8b851647d304c5 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 8 Nov 2013 10:34:05 +0100 Subject: [PATCH 034/130] Performance: Added OpenMP to mock models --- .../RigReservoirBuilderMock.cpp | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp index 116dc4e8d3..f62e9c90c6 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp @@ -135,10 +135,14 @@ void RigReservoirBuilderMock::appendCubeNodes(const cvf::Vec3d& min, const cvf:: void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCount, RigGridBase* hostGrid, std::vector& cells) { size_t activeCellIndex = 0; - size_t i; - for (i = 0; i < cellCount; i++) + long long i; + + cells.resize(cellCount); + +#pragma omp parallel for + for (i = 0; i < static_cast(cellCount); i++) { - RigCell riCell; + RigCell& riCell = cells[i]; riCell.setHostGrid(hostGrid); riCell.setCellIndex(i); @@ -165,8 +169,6 @@ void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCoun riCell.setActiveIndexInMatrixModel(activeCellIndex++); } */ - - cells.push_back(riCell); } } @@ -350,13 +352,15 @@ bool RigReservoirBuilderMock::dynamicResult(RigCaseData* eclipseCase, const QStr double scaleValue = 1.0 + resultIndex * 0.1; double offsetValue = 100 * resultIndex; - size_t k; - for (k = 0; k < eclipseCase->mainGrid()->cells().size(); k++) + values->resize(eclipseCase->mainGrid()->cells().size()); + +#pragma omp parallel for + for (long long k = 0; k < static_cast(eclipseCase->mainGrid()->cells().size()); k++) { RigCell& cell = eclipseCase->mainGrid()->cells()[k]; { double val = offsetValue + scaleValue * ( (stepIndex * 1000 + k) % eclipseCase->mainGrid()->cells().size() ); - values->push_back(val); + values->at(k) = val; } } From b9b5441bdb5f060a7d8354104a25f29b059abf7b Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 8 Nov 2013 14:27:21 +0100 Subject: [PATCH 035/130] Performance: Reduce memory use for riGetPropertyData --- .../SocketInterface/RiaPropertyDataCommands.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index 40dc5d2efd..f31218d7e3 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -304,10 +304,10 @@ class RiaGetGridProperty: public RiaSocketCommand quint64 timestepCount = (quint64)requestedTimesteps.size(); socketStream << timestepCount; - size_t doubleValueCount = cellCountI * cellCountJ * cellCountK * timestepCount * sizeof(double); - std::vector values(doubleValueCount); size_t valueIdx = 0; + std::vector values(rigGrid->cellCount()); + for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); @@ -323,11 +323,11 @@ class RiaGetGridProperty: public RiaSocketCommand { cellValue = 0.0; } - values[valueIdx++] = cellValue; + values[cellIdx] = cellValue; } - } - server->currentClient()->write((const char *)values.data(), doubleValueCount); + server->currentClient()->write((const char *)values.data(), rigGrid->cellCount() * sizeof(double)); + } return true; } From 7c42bf013869609c4989dc3f7aa82c1f25e1bacf Mon Sep 17 00:00:00 2001 From: magnesj Date: Mon, 11 Nov 2013 14:36:59 +0100 Subject: [PATCH 036/130] Temporarily fixes for handling communication of more than 2GB data to/from octave --- OctavePlugin/riGetActiveCellProperty.cpp | 4 +- OctavePlugin/riGetGridProperty.cpp | 85 +++++++++++++++++++++--- OctavePlugin/riSetGridProperty.cpp | 13 ++-- 3 files changed, 87 insertions(+), 15 deletions(-) diff --git a/OctavePlugin/riGetActiveCellProperty.cpp b/OctavePlugin/riGetActiveCellProperty.cpp index a936b82d96..81b966f7d0 100644 --- a/OctavePlugin/riGetActiveCellProperty.cpp +++ b/OctavePlugin/riGetActiveCellProperty.cpp @@ -67,7 +67,7 @@ void getActiveCellProperty(Matrix& propertyFrames, const QString &serverName, qu for (size_t tIdx = 0; tIdx < timestepCount; ++tIdx) { - while (socket.bytesAvailable() < (int)byteCount) + while (socket.bytesAvailable() < (qint64)byteCount) { if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) { @@ -94,7 +94,7 @@ void getActiveCellProperty(Matrix& propertyFrames, const QString &serverName, qu } #endif - if ((int)byteCount != bytesRead) + if ((qint64)byteCount != bytesRead) { error("Could not read binary double data properly from socket"); octave_stdout << "Active cells: " << activeCellCount << ", Timesteps: " << timestepCount << std::endl; diff --git a/OctavePlugin/riGetGridProperty.cpp b/OctavePlugin/riGetGridProperty.cpp index 3771341644..3b1fbc589f 100644 --- a/OctavePlugin/riGetGridProperty.cpp +++ b/OctavePlugin/riGetGridProperty.cpp @@ -22,7 +22,7 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 QString command; command += "GetGridProperty " + QString::number(caseId) + " " + QString::number(gridIdx) + " " + propertyName + " " + porosityModel; - for (int i = 0; i < requestedTimeSteps.length(); ++i) + for (qint64 i = 0; i < requestedTimeSteps.length(); ++i) { if (i == 0) command += " "; command += QString::number(static_cast(requestedTimeSteps.elem(i)) - 1); // To make the index 0-based @@ -36,7 +36,7 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 // Get response. First wait for the header - while (socket.bytesAvailable() < (int)(4*sizeof(quint64))) + while (socket.bytesAvailable() < (qint64)(4*sizeof(quint64))) { if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) { @@ -48,6 +48,7 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 // Read sizes quint64 totalByteCount; + quint64 cellCountI; quint64 cellCountJ; quint64 cellCountK; @@ -59,6 +60,9 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 socketStream >> timestepCount; totalByteCount = cellCountI*cellCountJ*cellCountK*timestepCount*sizeof(double); + + qint64 timestepByteCount = cellCountI*cellCountJ*cellCountK*sizeof(double); + if (!(totalByteCount)) { error ("Could not find the requested data in ResInsight"); @@ -75,29 +79,92 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 propertyFrames.resize(dv); - // Wait for available data +#if 1 + // Wait for available data for each timestep, then read data for each timestep + + qint64 totalBytesRead = 0; + + for (size_t tIdx = 0; tIdx < timestepCount; ++tIdx) + { + qint64 bytesAvailable = socket.bytesAvailable() ; + + while ( bytesAvailable < (qint64)timestepByteCount) + { + if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) + { + error((("Waiting for timestep data number: ") + QString::number(tIdx)+ ": " + socket.errorString()).toLatin1().data()); + octave_stdout << "Cellcount: " << cellCountI*cellCountJ*cellCountK << ", Timesteps: " << timestepCount << std::endl; + return ; + } + + bytesAvailable = socket.bytesAvailable(); + + OCTAVE_QUIT; + } - while (socket.bytesAvailable() < (int)totalByteCount) + qint64 bytesRead = 0; + double * internalMatrixData = propertyFrames.fortran_vec(); + + // Raw data transfer. Faster. Not possible when dealing with coarsening + bytesRead = socket.read(((char*)(internalMatrixData)) + tIdx * timestepByteCount, timestepByteCount); + + if ((qint64)timestepByteCount != bytesRead) + { + error("Could not read binary double data properly from socket"); + octave_stdout << "Cellcount: " << cellCountI*cellCountJ*cellCountK << ", Timesteps count: " << timestepCount << std::endl; + octave_stdout << "Timestep : " << tIdx << std::endl; + } + + totalBytesRead += bytesRead; + + OCTAVE_QUIT; + } + + if ((qint64)totalByteCount != totalBytesRead) { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) + error("Could not read binary double data properly from socket"); + } + + #else + + // Wait for available data + qint64 bytesAvailable = socket.bytesAvailable() ; + + while (bytesAvailable < (qint64)totalByteCount) + { + octave_stdout << "Waiting for data. Has : " << bytesAvailable << " Needs :" << totalByteCount << std::endl; + if (!socket.waitForReadyRead(riOctavePlugin::shortTimeOutMilliSecs)) { - error(("Waiting for data : " + socket.errorString()).toLatin1().data()); - return ; + //error(("Waiting for data : " + socket.errorString()).toLatin1().data()); + //return ; } + + bytesAvailable = socket.bytesAvailable() ; OCTAVE_QUIT; } qint64 bytesRead = 0; double * internalMatrixData = propertyFrames.fortran_vec(); +#if 0 + + char* dataBuffer = new char[totalByteCount]; + bytesRead = socket.read(dataBuffer, totalByteCount); + + +#else + // Raw data transfer. Faster. bytesRead = socket.read((char*)(internalMatrixData ), totalByteCount); +#endif - if ((int)totalByteCount != bytesRead) + + if ((qint64)totalByteCount != bytesRead) { error("Could not read binary double data properly from socket"); } - + +#endif QString tmp = QString("riGetGridProperty : Read %1").arg(propertyName); if (caseId < 0) diff --git a/OctavePlugin/riSetGridProperty.cpp b/OctavePlugin/riSetGridProperty.cpp index 04773e8804..f5afe0a0f7 100644 --- a/OctavePlugin/riSetGridProperty.cpp +++ b/OctavePlugin/riSetGridProperty.cpp @@ -64,8 +64,13 @@ void setEclipseProperty(const NDArray& propertyFrames, const QString &hostName, socketStream << (qint64)singleTimeStepByteCount; const double* internalData = propertyFrames.fortran_vec(); - int dataWritten = socket.write((const char *)internalData, singleTimeStepByteCount*timeStepCount); - + qint64 dataWritten = 0; + + for (size_t tsIdx = 0; tsIdx < timeStepCount; ++tsIdx) + { + dataWritten += socket.write(((const char *)internalData) + tsIdx*singleTimeStepByteCount, singleTimeStepByteCount); + } + if (dataWritten == singleTimeStepByteCount*timeStepCount) { QString tmp = QString("riSetGridProperty : Wrote %1").arg(propertyName); @@ -92,8 +97,8 @@ void setEclipseProperty(const NDArray& propertyFrames, const QString &hostName, while(socket.bytesToWrite() && socket.state() == QAbstractSocket::ConnectedState) { - // octave_stdout << "Bytes to write: " << socket.bytesToWrite() << std::endl; - socket.waitForBytesWritten(riOctavePlugin::longTimeOutMilliSecs); + octave_stdout << "Bytes to write: " << socket.bytesToWrite() << std::endl << std::flush; + socket.waitForBytesWritten(2000); OCTAVE_QUIT; } From 3ec22a92212c54b7f6c502c9c1cb7ce6a4c34aab Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 1 Apr 2014 13:02:52 +0200 Subject: [PATCH 037/130] Added flag to control how to do IO with sockets --- .../Application/RiaPreferences.cpp | 1 + ApplicationCode/Application/RiaPreferences.h | 2 + .../SocketInterface/RiaGeometryCommands.cpp | 62 +++++++++++++++---- .../RiaPropertyDataCommands.cpp | 55 ++++++++++++---- 4 files changed, 96 insertions(+), 24 deletions(-) diff --git a/ApplicationCode/Application/RiaPreferences.cpp b/ApplicationCode/Application/RiaPreferences.cpp index 3e45619055..5c060c7031 100644 --- a/ApplicationCode/Application/RiaPreferences.cpp +++ b/ApplicationCode/Application/RiaPreferences.cpp @@ -60,6 +60,7 @@ RiaPreferences::RiaPreferences(void) CAF_PDM_InitField(&autocomputeDepthRelatedProperties,"autocomputeDepth", true, "DEPTH related properties", "", "DEPTH, DX, DY, DZ, TOP, BOTTOM", ""); CAF_PDM_InitField(&readFaultData, "readFaultData", true, "Read fault data", "", "", ""); + CAF_PDM_InitField(&useStreamTransfer, "useStreamTransfer", true, "Use stream transfer to Octave", "", "", ""); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Application/RiaPreferences.h b/ApplicationCode/Application/RiaPreferences.h index 4623599926..5fcc691d3c 100644 --- a/ApplicationCode/Application/RiaPreferences.h +++ b/ApplicationCode/Application/RiaPreferences.h @@ -60,6 +60,8 @@ class RiaPreferences : public caf::PdmObject caf::PdmField readFaultData; + caf::PdmField useStreamTransfer; + protected: virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); diff --git a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp index 2ec5878cb6..413f4791bc 100644 --- a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp @@ -34,6 +34,8 @@ #include "RigCaseCellResultsData.h" #include +#include "RiaApplication.h" +#include "RiaPreferences.h" //-------------------------------------------------------------------------------------------------- @@ -241,32 +243,66 @@ class RiaGetCellCorners : public RiaSocketCommand // dv(3) = 8; // dv(4) = 3; - std::vector cellCornerValues(doubleValueCount); - cvf::Vec3d cornerVerts[8]; - quint64 coordCount = 0; - for (int coordIdx = 0; coordIdx < 3; coordIdx++) + cvf::Timer timer; + + if (RiaApplication::instance()->preferences()->useStreamTransfer()) { - for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) + cvf::Vec3d cornerVerts[8]; + for (int coordIdx = 0; coordIdx < 3; coordIdx++) { - size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; + for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) + { + size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; + + for (size_t k = 0; k < cellCountK; k++) + { + for (size_t j = 0; j < cellCountJ; j++) + { + for (size_t i = 0; i < cellCountI; i++) + { + size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); + rigGrid->cellCornerVertices(localCellIdx, cornerVerts); - for (size_t k = 0; k < cellCountK; k++) + socketStream << cornerVerts[cornerIndexMapping][coordIdx]; + } + } + } + } + } + } + else + { + std::vector cellCornerValues(doubleValueCount); + cvf::Vec3d cornerVerts[8]; + quint64 coordCount = 0; + for (int coordIdx = 0; coordIdx < 3; coordIdx++) + { + for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) { - for (size_t j = 0; j < cellCountJ; j++) + size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; + + for (size_t k = 0; k < cellCountK; k++) { - for (size_t i = 0; i < cellCountI; i++) + for (size_t j = 0; j < cellCountJ; j++) { - size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); - rigGrid->cellCornerVertices(localCellIdx, cornerVerts); + for (size_t i = 0; i < cellCountI; i++) + { + size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); + rigGrid->cellCornerVertices(localCellIdx, cornerVerts); - cellCornerValues[coordCount++] = cornerVerts[cornerIndexMapping][coordIdx]; + cellCornerValues[coordCount++] = cornerVerts[cornerIndexMapping][coordIdx]; + } } } } } + server->currentClient()->write((const char *)cellCornerValues.data(), byteCount); } - server->currentClient()->write((const char *)cellCornerValues.data(), byteCount); + double totalTimeMS = timer.time() * 1000.0; + QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); + + server->errorMessageDialog()->showMessage(resultInfo); return true; } diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index f31218d7e3..4fa6a4f841 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -40,6 +40,8 @@ #include "Rim3dOverlayInfoConfig.h" #include +#include "RiaApplication.h" +#include "RiaPreferences.h" //-------------------------------------------------------------------------------------------------- @@ -305,30 +307,61 @@ class RiaGetGridProperty: public RiaSocketCommand socketStream << timestepCount; size_t valueIdx = 0; - - std::vector values(rigGrid->cellCount()); + cvf::Timer timer; - for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) + if (RiaApplication::instance()->preferences()->useStreamTransfer()) { - cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); - if (cellCenterDataAccessObject.isNull()) + for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { - continue; + cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); + if (cellCenterDataAccessObject.isNull()) + { + continue; + } + + for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) + { + double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); + if (cellValue == HUGE_VAL) + { + cellValue = 0.0; + } + + socketStream << cellValue; + } } + } + else + { - for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) + std::vector values(rigGrid->cellCount()); + for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { - double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); - if (cellValue == HUGE_VAL) + cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); + if (cellCenterDataAccessObject.isNull()) { - cellValue = 0.0; + continue; + } + + for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) + { + double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); + if (cellValue == HUGE_VAL) + { + cellValue = 0.0; + } + values[valueIdx++] = cellValue; } - values[cellIdx] = cellValue; } server->currentClient()->write((const char *)values.data(), rigGrid->cellCount() * sizeof(double)); } + double totalTimeMS = timer.time() * 1000.0; + QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); + + server->errorMessageDialog()->showMessage(resultInfo); + return true; } }; From 039ba48bed490e0c7cc693df66a9a67fdee0fe10 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 1 Apr 2014 15:31:13 +0200 Subject: [PATCH 038/130] Added block write to socket tools --- .../Application/RiaPreferences.cpp | 1 + ApplicationCode/Application/RiaPreferences.h | 1 + .../SocketInterface/RiaCaseInfoCommands.cpp | 9 +++- .../SocketInterface/RiaGeometryCommands.cpp | 10 ++-- .../RiaPropertyDataCommands.cpp | 5 +- .../SocketInterface/RiaSocketTools.cpp | 47 +++++++++++++++++++ .../SocketInterface/RiaSocketTools.h | 3 ++ 7 files changed, 67 insertions(+), 9 deletions(-) diff --git a/ApplicationCode/Application/RiaPreferences.cpp b/ApplicationCode/Application/RiaPreferences.cpp index 5c060c7031..793c2ffc9c 100644 --- a/ApplicationCode/Application/RiaPreferences.cpp +++ b/ApplicationCode/Application/RiaPreferences.cpp @@ -61,6 +61,7 @@ RiaPreferences::RiaPreferences(void) CAF_PDM_InitField(&readFaultData, "readFaultData", true, "Read fault data", "", "", ""); CAF_PDM_InitField(&useStreamTransfer, "useStreamTransfer", true, "Use stream transfer to Octave", "", "", ""); + CAF_PDM_InitField(&blockSize, "blockSize", 10000, "blockSize", "", "", ""); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Application/RiaPreferences.h b/ApplicationCode/Application/RiaPreferences.h index 5fcc691d3c..785eccf6d6 100644 --- a/ApplicationCode/Application/RiaPreferences.h +++ b/ApplicationCode/Application/RiaPreferences.h @@ -61,6 +61,7 @@ class RiaPreferences : public caf::PdmObject caf::PdmField readFaultData; caf::PdmField useStreamTransfer; + caf::PdmField blockSize; protected: virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); diff --git a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp index 201267dfb0..e6444f314d 100644 --- a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp @@ -16,9 +16,12 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RiaStdInclude.h" + #include "RiaSocketCommand.h" #include "RiaSocketServer.h" #include "RiaSocketTools.h" +#include "RiaApplication.h" +#include "RiaPreferences.h" #include "RimReservoirView.h" #include "RimResultSlot.h" @@ -28,8 +31,8 @@ #include "RimWellCollection.h" #include "Rim3dOverlayInfoConfig.h" #include "RimReservoirCellResultsCacher.h" - #include "RimCase.h" + #include "RigCaseData.h" #include "RigCaseCellResultsData.h" @@ -37,6 +40,7 @@ + //-------------------------------------------------------------------------------------------------- /// OBSOLETE, to be deleted //-------------------------------------------------------------------------------------------------- @@ -133,7 +137,8 @@ class RiaGetActiveCellInfo: public RiaSocketCommand for (size_t tIdx = 0; tIdx < columnCount; ++tIdx) { #if 1 // Write data as raw bytes, fast but does not handle byteswapping - server->currentClient()->write((const char *)activeCellInfo[tIdx].data(), timestepByteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)activeCellInfo[tIdx].data(), timestepByteCount); + #else // Write data using QDataStream, does byteswapping for us. Must use QDataStream on client as well for (size_t cIdx = 0; cIdx < activeCellInfo[tIdx].size(); ++cIdx) { diff --git a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp index 413f4791bc..5a3c8bc8b7 100644 --- a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp @@ -38,6 +38,7 @@ #include "RiaPreferences.h" + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -108,7 +109,7 @@ class RiaGetCellCenters : public RiaSocketCommand CVF_ASSERT(coordCount == doubleValueCount); - server->currentClient()->write((const char *)cellCenterValues.data(), byteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCenterValues.data(), byteCount); return true; } @@ -181,7 +182,7 @@ class RiaGetActiveCellCenters : public RiaSocketCommand quint64 byteCount = doubleValueCount * sizeof(double); socketStream << byteCount; - server->currentClient()->write((const char *)cellCenterValues.data(), byteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCenterValues.data(), byteCount); return true; } @@ -296,7 +297,8 @@ class RiaGetCellCorners : public RiaSocketCommand } } } - server->currentClient()->write((const char *)cellCornerValues.data(), byteCount); + + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCornerValues.data(), byteCount); } double totalTimeMS = timer.time() * 1000.0; @@ -381,7 +383,7 @@ class RiaGetActiveCellCorners : public RiaSocketCommand quint64 byteCount = doubleValueCount * sizeof(double); socketStream << byteCount; - server->currentClient()->write((const char *)cellCornerValues.data(), byteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCornerValues.data(), byteCount); return true; } diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index 4fa6a4f841..00210e4e21 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -334,7 +334,6 @@ class RiaGetGridProperty: public RiaSocketCommand else { - std::vector values(rigGrid->cellCount()); for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); @@ -343,6 +342,7 @@ class RiaGetGridProperty: public RiaSocketCommand continue; } + std::vector values(rigGrid->cellCount()); for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) { double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); @@ -352,9 +352,8 @@ class RiaGetGridProperty: public RiaSocketCommand } values[valueIdx++] = cellValue; } + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), values.size() * sizeof(double)); } - - server->currentClient()->write((const char *)values.data(), rigGrid->cellCount() * sizeof(double)); } double totalTimeMS = timer.time() * 1000.0; diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.cpp b/ApplicationCode/SocketInterface/RiaSocketTools.cpp index cc53f26824..4ad720d2a9 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketTools.cpp @@ -16,6 +16,10 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RiaStdInclude.h" + +#include "RiaApplication.h" +#include "RiaPreferences.h" + #include "RiaSocketTools.h" #include "RiaSocketServer.h" #include "RimCase.h" @@ -34,6 +38,8 @@ #include "RimInputPropertyCollection.h" +#include + //-------------------------------------------------------------------------------------------------- /// @@ -98,4 +104,45 @@ void RiaSocketTools::getCaseInfoFromCase(RimCase* rimCase, qint64& caseId, QStri } } +bool RiaSocketTools::writeBlockData(RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite) +{ + cvf::Timer timer; + + quint64 bytesWritten = 0; + int blockCount = 0; + + quint64 maxBlockSize = RiaApplication::instance()->preferences()->blockSize(); + + while (bytesWritten < bytesToWrite) + { + quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize); + + quint64 actuallyBytesWritten = socket->write(data + bytesWritten, byteCountToWrite); + if (actuallyBytesWritten == -1) + { + if (server) + { + QString errorMessage = "Error detected when writing data, error string from socket : \n" + socket->errorString(); + + server->errorMessageDialog()->showMessage(errorMessage); + } + + return false; + } + + bytesWritten += actuallyBytesWritten; + + blockCount++; + } + + if (server) + { + double totalTimeMS = timer.time() * 1000.0; + QString resultInfo = QString("Total time '%1 ms'\nTotal bytes written . %2\nNumber of blocks : %3\nBlock size : %4").arg(totalTimeMS).arg(bytesWritten).arg(blockCount).arg(maxBlockSize); + + server->errorMessageDialog()->showMessage(resultInfo); + } + + return true; +} diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.h b/ApplicationCode/SocketInterface/RiaSocketTools.h index 1baeb5a9fc..b331799e2e 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.h +++ b/ApplicationCode/SocketInterface/RiaSocketTools.h @@ -17,6 +17,7 @@ class RimCase; class RiaSocketServer; +class QTcpSocket; #define PMonLog( MessageString ) RiuMainWindow::instance()->processMonitor()->addStringToLog( MessageString ); @@ -25,4 +26,6 @@ class RiaSocketTools public: static RimCase* findCaseFromArgs(RiaSocketServer* server, const QList& args); static void getCaseInfoFromCase(RimCase* rimCase, qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId); + + static bool writeBlockData(RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite); }; From c1419e53e895ecbdf3cc6593b7d9a538039820fa Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 1 Apr 2014 15:36:08 +0200 Subject: [PATCH 039/130] Fixed used on unsigned --- ApplicationCode/SocketInterface/RiaSocketTools.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.cpp b/ApplicationCode/SocketInterface/RiaSocketTools.cpp index 4ad720d2a9..0f645450f9 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketTools.cpp @@ -113,12 +113,13 @@ bool RiaSocketTools::writeBlockData(RiaSocketServer* server, QTcpSocket* socket, quint64 maxBlockSize = RiaApplication::instance()->preferences()->blockSize(); + while (bytesWritten < bytesToWrite) { quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize); - quint64 actuallyBytesWritten = socket->write(data + bytesWritten, byteCountToWrite); - if (actuallyBytesWritten == -1) + qint64 actuallyBytesWritten = socket->write(data + bytesWritten, byteCountToWrite); + if (actuallyBytesWritten < 0) { if (server) { From 364ea1f9371c2898c1f8b9d1859906770639655f Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Wed, 2 Apr 2014 08:55:26 +0200 Subject: [PATCH 040/130] Added block read from socket --- .../SocketInterface/RiaSocketTools.cpp | 43 +++++++++++++++++++ .../SocketInterface/RiaSocketTools.h | 1 + OctavePlugin/riGetCellCorners.cpp | 17 ++++++++ 3 files changed, 61 insertions(+) diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.cpp b/ApplicationCode/SocketInterface/RiaSocketTools.cpp index 0f645450f9..64cc8e0c11 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketTools.cpp @@ -147,3 +147,46 @@ bool RiaSocketTools::writeBlockData(RiaSocketServer* server, QTcpSocket* socket, return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiaSocketTools::readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages) +{ + quint64 bytesRead = 0; + int blockCount = 0; + + quint64 maxBlockSize = RiaApplication::instance()->preferences()->blockSize(); + + while (bytesRead < bytesToRead) + { + if (socket.bytesAvailable()) + { + quint64 byteCountToRead = qMin(bytesToRead - bytesRead, maxBlockSize); + + qint64 actuallyBytesRead = socket.read(data + bytesRead, byteCountToRead); + if (actuallyBytesRead < 0) + { + errorMessages.push_back("Error detected when writing data, error string from socket"); + errorMessages.push_back(socket.errorString()); + + return false; + } + + bytesRead += actuallyBytesRead; + blockCount++; + } + else + { + if (!socket.waitForReadyRead()) + { + errorMessages.push_back("Waited for data for %1 milli seconds."); + errorMessages.push_back(socket.errorString()); + + return false; + } + } + } + + return true; +} + diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.h b/ApplicationCode/SocketInterface/RiaSocketTools.h index b331799e2e..5a24731237 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.h +++ b/ApplicationCode/SocketInterface/RiaSocketTools.h @@ -28,4 +28,5 @@ class RiaSocketTools static void getCaseInfoFromCase(RimCase* rimCase, qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId); static bool writeBlockData(RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite); + static bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages); }; diff --git a/OctavePlugin/riGetCellCorners.cpp b/OctavePlugin/riGetCellCorners.cpp index ee8f810239..af659079c0 100644 --- a/OctavePlugin/riGetCellCorners.cpp +++ b/OctavePlugin/riGetCellCorners.cpp @@ -1,7 +1,10 @@ #include +#include + #include #include "riSettings.h" +#include "../ApplicationCode/SocketInterface/RiaSocketTools.h" void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 port, const qint32& caseId, const quint32& gridIndex) @@ -67,7 +70,20 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 dv(4) = 3; cellCornerValues.resize(dv); + double* internalMatrixData = cellCornerValues.fortran_vec(); + QStringList errorMessages; + if (!RiaSocketTools::readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) + { + for (int i = 0; i < errorMessages.size(); i++) + { + error(errorMessages[i].toLatin1().data()); + } + + OCTAVE_QUIT; + } + + /* while (socket.bytesAvailable() < (qint64)(byteCount)) { if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) @@ -97,6 +113,7 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 } #endif + */ return; } From ed216f6de3511f2ac1fc47370618662ff60d72bc Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Wed, 2 Apr 2014 09:52:02 +0200 Subject: [PATCH 041/130] Moved Octave socket reading into riSocketTools --- OctavePlugin/riGetCellCorners.cpp | 8 ++++-- OctavePlugin/riGetCurrentCase.cpp | 1 + OctavePlugin/riSocketTools.h | 46 +++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 OctavePlugin/riSocketTools.h diff --git a/OctavePlugin/riGetCellCorners.cpp b/OctavePlugin/riGetCellCorners.cpp index af659079c0..f5e3b2c356 100644 --- a/OctavePlugin/riGetCellCorners.cpp +++ b/OctavePlugin/riGetCellCorners.cpp @@ -4,7 +4,9 @@ #include #include "riSettings.h" -#include "../ApplicationCode/SocketInterface/RiaSocketTools.h" +#include "riSocketTools.h" + + void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 port, const qint32& caseId, const quint32& gridIndex) @@ -72,7 +74,7 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 double* internalMatrixData = cellCornerValues.fortran_vec(); QStringList errorMessages; - if (!RiaSocketTools::readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) + if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) { for (int i = 0; i < errorMessages.size(); i++) { @@ -82,6 +84,8 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 OCTAVE_QUIT; } + octave_stdout << "Bytes count processed : " << byteCount << std::endl; + /* while (socket.bytesAvailable() < (qint64)(byteCount)) diff --git a/OctavePlugin/riGetCurrentCase.cpp b/OctavePlugin/riGetCurrentCase.cpp index 80b0ffe4ac..88cc38088d 100644 --- a/OctavePlugin/riGetCurrentCase.cpp +++ b/OctavePlugin/riGetCurrentCase.cpp @@ -3,6 +3,7 @@ #include #include "riSettings.h" +#include "riSocketTools.h" void getCurrentCase(qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId, const QString &hostName, quint16 port) { diff --git a/OctavePlugin/riSocketTools.h b/OctavePlugin/riSocketTools.h new file mode 100644 index 0000000000..7d01381668 --- /dev/null +++ b/OctavePlugin/riSocketTools.h @@ -0,0 +1,46 @@ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages) +{ + quint64 bytesRead = 0; + int blockCount = 0; + + quint64 maxBlockSize = 100000; + + while (bytesRead < bytesToRead) + { + if (socket.bytesAvailable()) + { + quint64 byteCountToRead = qMin(bytesToRead - bytesRead, maxBlockSize); + + qint64 actuallyBytesRead = socket.read(data + bytesRead, byteCountToRead); + if (actuallyBytesRead < 0) + { + errorMessages.push_back("Error detected when writing data, error string from socket"); + errorMessages.push_back(socket.errorString()); + + return false; + } + + bytesRead += actuallyBytesRead; + + octave_stdout << "Bytes read " << bytesRead << " of total " << bytesToRead << std::endl; + + blockCount++; + } + else + { + if (!socket.waitForReadyRead()) + { + errorMessages.push_back("Waited for data for %1 milli seconds."); + errorMessages.push_back(socket.errorString()); + + return false; + } + } + } + + return true; +} From 0bdacfba1729329cb1ec5cf6429dc643efefb15e Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 3 Apr 2014 08:16:15 +0200 Subject: [PATCH 042/130] Moved socket max byte count to riSettings Added header files to cmake --- OctavePlugin/CMakeLists.txt | 5 ++++- OctavePlugin/riSettings.h | 2 ++ OctavePlugin/riSocketTools.h | 38 ++++++++++++++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/OctavePlugin/CMakeLists.txt b/OctavePlugin/CMakeLists.txt index 68a4b588d3..7a11e18ab9 100644 --- a/OctavePlugin/CMakeLists.txt +++ b/OctavePlugin/CMakeLists.txt @@ -141,7 +141,10 @@ if (RESINSIGHT_OCTAVE_PLUGIN_QMAKE AND RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE) "${CMAKE_CURRENT_BINARY_DIR}/riGetWellNames.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetWellStatus.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetWellCells.oct" - SOURCES ${CPP_SOURCES} + SOURCES + ${CPP_SOURCES} + riSocketTools.h + riSettings.h ) diff --git a/OctavePlugin/riSettings.h b/OctavePlugin/riSettings.h index bc7220e845..5765244a6d 100644 --- a/OctavePlugin/riSettings.h +++ b/OctavePlugin/riSettings.h @@ -24,6 +24,8 @@ namespace riOctavePlugin const int shortTimeOutMilliSecs = 5000; const int longTimeOutMilliSecs = 6000000; + const int socketMaxByteCount = 100000; + // Octave data structure : CaseInfo char caseInfo_CaseId[] = "CaseId"; char caseInfo_CaseName[] = "CaseName"; diff --git a/OctavePlugin/riSocketTools.h b/OctavePlugin/riSocketTools.h index 7d01381668..63cc24d890 100644 --- a/OctavePlugin/riSocketTools.h +++ b/OctavePlugin/riSocketTools.h @@ -7,7 +7,7 @@ bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringL quint64 bytesRead = 0; int blockCount = 0; - quint64 maxBlockSize = 100000; + quint64 maxBlockSize = riOctavePlugin::socketMaxByteCount; while (bytesRead < bytesToRead) { @@ -18,7 +18,7 @@ bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringL qint64 actuallyBytesRead = socket.read(data + bytesRead, byteCountToRead); if (actuallyBytesRead < 0) { - errorMessages.push_back("Error detected when writing data, error string from socket"); + errorMessages.push_back("Error detected when reading data, error string from socket :"); errorMessages.push_back(socket.errorString()); return false; @@ -41,6 +41,40 @@ bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringL } } } + + octave_stdout << "Bytes read " << bytesToRead << std::endl; + + return true; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool writeBlockData(QTcpSocket& socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages) +{ + quint64 bytesWritten = 0; + int blockCount = 0; + + quint64 maxBlockSize = riOctavePlugin::socketMaxByteCount; + + while (bytesWritten < bytesToWrite) + { + quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize); + + qint64 actuallyBytesWritten = socket.write(data + bytesWritten, byteCountToWrite); + if (actuallyBytesWritten < 0) + { + errorMessages.push_back("Error detected when writing data, error string from socket"); + errorMessages.push_back(socket.errorString()); + + return false; + } + + bytesWritten += actuallyBytesWritten; + + blockCount++; + } return true; } From acc1d732d7b05df3de19834f8da7e46d4e3aeb0f Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 3 Apr 2014 10:41:27 +0200 Subject: [PATCH 043/130] Use socket block read/write for geometry data --- .../SocketInterface/RiaGeometryCommands.cpp | 127 ++++++++---------- OctavePlugin/riGetActiveCellCenters.cpp | 23 ++-- OctavePlugin/riGetActiveCellCorners.cpp | 23 ++-- OctavePlugin/riGetCellCenters.cpp | 37 ++--- OctavePlugin/riGetCellCorners.cpp | 35 ----- 5 files changed, 82 insertions(+), 163 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp index 5a3c8bc8b7..2ca72a655d 100644 --- a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp @@ -87,11 +87,14 @@ class RiaGetCellCenters : public RiaSocketCommand // dv(2) = cellCountK; // dv(3) = 3; - std::vector cellCenterValues(doubleValueCount); cvf::Vec3d cornerVerts[8]; - quint64 coordCount = 0; + size_t blockByteCount = cellCount * sizeof(double); + std::vector doubleValues(blockByteCount); + for (int coordIdx = 0; coordIdx < 3; coordIdx++) { + quint64 valueIndex = 0; + for (size_t k = 0; k < cellCountK; k++) { for (size_t j = 0; j < cellCountJ; j++) @@ -101,15 +104,15 @@ class RiaGetCellCenters : public RiaSocketCommand size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); cvf::Vec3d center = rigGrid->cell(localCellIdx).center(); - cellCenterValues[coordCount++] = center[coordIdx]; + doubleValues[valueIndex++] = center[coordIdx]; } } } - } - CVF_ASSERT(coordCount == doubleValueCount); + CVF_ASSERT(valueIndex == cellCount); - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCenterValues.data(), byteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); + } return true; } @@ -152,6 +155,11 @@ class RiaGetActiveCellCenters : public RiaSocketCommand size_t activeCellCount = actCellInfo->globalActiveCellCount(); size_t doubleValueCount = activeCellCount * 3; + socketStream << (quint64)activeCellCount; + quint64 byteCount = doubleValueCount * sizeof(double); + socketStream << byteCount; + + // This structure is supposed to be received by Octave using a NDArray. The ordering of this loop is // defined by the ordering of the receiving NDArray // @@ -162,27 +170,25 @@ class RiaGetActiveCellCenters : public RiaSocketCommand // dv(0) = coordCount; // dv(1) = 3; - std::vector cellCenterValues(doubleValueCount); - quint64 coordCount = 0; + size_t blockByteCount = activeCellCount * sizeof(double); + std::vector doubleValues(blockByteCount); + for (int coordIdx = 0; coordIdx < 3; coordIdx++) { + quint64 valueIndex = 0; + for (size_t globalCellIdx = 0; globalCellIdx < mainGrid->cells().size(); globalCellIdx++) { if (!actCellInfo->isActive(globalCellIdx)) continue; cvf::Vec3d center = mainGrid->cells()[globalCellIdx].center(); - cellCenterValues[coordCount++] = center[coordIdx]; + doubleValues[valueIndex++] = center[coordIdx]; } - } - - CVF_ASSERT(coordCount == doubleValueCount); - socketStream << (quint64)activeCellCount; - quint64 byteCount = doubleValueCount * sizeof(double); - socketStream << byteCount; - - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCenterValues.data(), byteCount); + CVF_ASSERT(valueIndex == activeCellCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); + } return true; } @@ -244,67 +250,37 @@ class RiaGetCellCorners : public RiaSocketCommand // dv(3) = 8; // dv(4) = 3; - cvf::Timer timer; + cvf::Vec3d cornerVerts[8]; + size_t blockByteCount = cellCount * sizeof(double); + std::vector doubleValues(blockByteCount); - if (RiaApplication::instance()->preferences()->useStreamTransfer()) + for (int coordIdx = 0; coordIdx < 3; coordIdx++) { - cvf::Vec3d cornerVerts[8]; - for (int coordIdx = 0; coordIdx < 3; coordIdx++) + for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) { - for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) - { - size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; + size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; - for (size_t k = 0; k < cellCountK; k++) - { - for (size_t j = 0; j < cellCountJ; j++) - { - for (size_t i = 0; i < cellCountI; i++) - { - size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); - rigGrid->cellCornerVertices(localCellIdx, cornerVerts); + quint64 valueIndex = 0; - socketStream << cornerVerts[cornerIndexMapping][coordIdx]; - } - } - } - } - } - } - else - { - std::vector cellCornerValues(doubleValueCount); - cvf::Vec3d cornerVerts[8]; - quint64 coordCount = 0; - for (int coordIdx = 0; coordIdx < 3; coordIdx++) - { - for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) + for (size_t k = 0; k < cellCountK; k++) { - size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; - - for (size_t k = 0; k < cellCountK; k++) + for (size_t j = 0; j < cellCountJ; j++) { - for (size_t j = 0; j < cellCountJ; j++) + for (size_t i = 0; i < cellCountI; i++) { - for (size_t i = 0; i < cellCountI; i++) - { - size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); - rigGrid->cellCornerVertices(localCellIdx, cornerVerts); + size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); + rigGrid->cellCornerVertices(localCellIdx, cornerVerts); - cellCornerValues[coordCount++] = cornerVerts[cornerIndexMapping][coordIdx]; - } + doubleValues[valueIndex++] = cornerVerts[cornerIndexMapping][coordIdx]; } } } - } - - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCornerValues.data(), byteCount); - } - double totalTimeMS = timer.time() * 1000.0; - QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); + CVF_ASSERT(valueIndex, cellCount); - server->errorMessageDialog()->showMessage(resultInfo); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); + } + } return true; } @@ -348,6 +324,10 @@ class RiaGetActiveCellCorners : public RiaSocketCommand size_t activeCellCount = actCellInfo->globalActiveCellCount(); size_t doubleValueCount = activeCellCount * 3 * 8; + socketStream << (quint64)activeCellCount; + quint64 byteCount = doubleValueCount * sizeof(double); + socketStream << byteCount; + // This structure is supposed to be received by Octave using a NDArray. The ordering of this loop is // defined by the ordering of the receiving NDArray // @@ -359,31 +339,32 @@ class RiaGetActiveCellCorners : public RiaSocketCommand // dv(1) = 8; // dv(2) = 3; - std::vector cellCornerValues(doubleValueCount); cvf::Vec3d cornerVerts[8]; - quint64 coordCount = 0; + size_t blockByteCount = activeCellCount * sizeof(double); + std::vector doubleValues(blockByteCount); + for (int coordIdx = 0; coordIdx < 3; coordIdx++) { for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) { size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; + quint64 valueIndex = 0; + for (size_t globalCellIdx = 0; globalCellIdx < mainGrid->cells().size(); globalCellIdx++) { if (!actCellInfo->isActive(globalCellIdx)) continue; mainGrid->cellCornerVertices(globalCellIdx, cornerVerts); - cellCornerValues[coordCount++] = cornerVerts[cornerIndexMapping][coordIdx]; + doubleValues[valueIndex++] = cornerVerts[cornerIndexMapping][coordIdx]; } - } - } - socketStream << (quint64)activeCellCount; - quint64 byteCount = doubleValueCount * sizeof(double); - socketStream << byteCount; + CVF_ASSERT(valueIndex == activeCellCount); - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCornerValues.data(), byteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); + } + } return true; } diff --git a/OctavePlugin/riGetActiveCellCenters.cpp b/OctavePlugin/riGetActiveCellCenters.cpp index 90c1631f30..a98ba06bac 100644 --- a/OctavePlugin/riGetActiveCellCenters.cpp +++ b/OctavePlugin/riGetActiveCellCenters.cpp @@ -1,7 +1,10 @@ #include +#include + #include #include "riSettings.h" +#include "riSocketTools.h" void getActiveCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 port, const qint32& caseId, const QString& porosityModel) @@ -61,24 +64,16 @@ void getActiveCellCenters(NDArray& cellCenterValues, const QString &hostName, qu cellCenterValues.resize(dv); - while (socket.bytesAvailable() < (qint64)(byteCount)) + double* internalMatrixData = cellCenterValues.fortran_vec(); + QStringList errorMessages; + if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) + for (int i = 0; i < errorMessages.size(); i++) { - error((("Waiting for data: ") + socket.errorString()).toLatin1().data()); - return; + error(errorMessages[i].toLatin1().data()); } - OCTAVE_QUIT; - } - - quint64 bytesRead = 0; - double* internalMatrixData = cellCenterValues.fortran_vec(); - bytesRead = socket.read((char*)(internalMatrixData), byteCount); - if (byteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - octave_stdout << "Active cell count: " << activeCellCount << std::endl; + OCTAVE_QUIT; } return; diff --git a/OctavePlugin/riGetActiveCellCorners.cpp b/OctavePlugin/riGetActiveCellCorners.cpp index 6fb285cc4a..47ffad52bc 100644 --- a/OctavePlugin/riGetActiveCellCorners.cpp +++ b/OctavePlugin/riGetActiveCellCorners.cpp @@ -1,7 +1,10 @@ #include +#include + #include #include "riSettings.h" +#include "riSocketTools.h" void getActiveCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 port, const qint32& caseId, const QString& porosityModel) @@ -61,24 +64,16 @@ void getActiveCellCorners(NDArray& cellCornerValues, const QString &hostName, qu dv(2) = 3; cellCornerValues.resize(dv); - while (socket.bytesAvailable() < (qint64)(byteCount)) + double* internalMatrixData = cellCornerValues.fortran_vec(); + QStringList errorMessages; + if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) + for (int i = 0; i < errorMessages.size(); i++) { - error((("Waiting for data: ") + socket.errorString()).toLatin1().data()); - return; + error(errorMessages[i].toLatin1().data()); } - OCTAVE_QUIT; - } - - quint64 bytesRead = 0; - double* internalMatrixData = cellCornerValues.fortran_vec(); - bytesRead = socket.read((char*)(internalMatrixData), byteCount); - if (byteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - octave_stdout << "Active cell count: " << activeCellCount << std::endl; + OCTAVE_QUIT; } return; diff --git a/OctavePlugin/riGetCellCenters.cpp b/OctavePlugin/riGetCellCenters.cpp index cb65de3d01..4f57d08a2b 100644 --- a/OctavePlugin/riGetCellCenters.cpp +++ b/OctavePlugin/riGetCellCenters.cpp @@ -1,7 +1,10 @@ #include +#include + #include #include "riSettings.h" +#include "riSocketTools.h" void getCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 port, const qint32& caseId, const quint32& gridIndex) @@ -66,39 +69,19 @@ void getCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 dv(3) = 3; cellCenterValues.resize(dv); - while (socket.bytesAvailable() < (qint64)(byteCount)) - { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) - { - error((("Waiting for data: ") + socket.errorString()).toLatin1().data()); - return; - } - OCTAVE_QUIT; - } - - //octave_stdout << " riGetCellCenters : I = " << cellCountI <<" J = " << cellCountJ << " K = " << cellCountK << std::endl; - //octave_stdout << " riGetCellCenters : numDoubles = " << valueCount << std::endl; double* internalMatrixData = cellCenterValues.fortran_vec(); - -#if 0 - octave_idx_type valueCount = cellCenterValues.length(); - double val; - for (octave_idx_type i = 0; i < valueCount; i++) + QStringList errorMessages; + if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) { - socketStream >> internalMatrixData[i]; - } -#else - quint64 bytesRead = 0; - bytesRead = socket.read((char*)(internalMatrixData), byteCount); + for (int i = 0; i < errorMessages.size(); i++) + { + error(errorMessages[i].toLatin1().data()); + } - if (byteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - octave_stdout << "Cell count: " << cellCount << std::endl; + OCTAVE_QUIT; } -#endif return; } diff --git a/OctavePlugin/riGetCellCorners.cpp b/OctavePlugin/riGetCellCorners.cpp index f5e3b2c356..2571371a76 100644 --- a/OctavePlugin/riGetCellCorners.cpp +++ b/OctavePlugin/riGetCellCorners.cpp @@ -84,41 +84,6 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 OCTAVE_QUIT; } - octave_stdout << "Bytes count processed : " << byteCount << std::endl; - - - /* - while (socket.bytesAvailable() < (qint64)(byteCount)) - { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) - { - error((("Waiting for data: ") + socket.errorString()).toLatin1().data()); - return; - } - OCTAVE_QUIT; - } - - double* internalMatrixData = cellCornerValues.fortran_vec(); - -#if 0 - double val; - for (octave_idx_type i = 0; i < valueCount; i++) - { - socketStream >> internalMatrixData[i]; - } -#else - quint64 bytesRead = 0; - bytesRead = socket.read((char*)(internalMatrixData), byteCount); - - if (byteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - octave_stdout << "Cell count: " << cellCount << std::endl; - } - -#endif - */ - return; } From 874b05b119caeaf1563bdde425f04dfaaf74feac Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 3 Apr 2014 10:58:29 +0200 Subject: [PATCH 044/130] Added isCoarseningActive --- ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp | 8 ++++++++ ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h | 1 + 2 files changed, 9 insertions(+) diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp index bb0da770da..b58b17c5d4 100644 --- a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp @@ -193,6 +193,14 @@ void RigActiveCellInfo::clear() m_activeCellsBoundingBox.reset(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigActiveCellInfo::isCoarseningActive() const +{ + return m_globalCellResultCount != m_globalActiveCellCount; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h index 2719dbffb5..cbe11c9b8c 100644 --- a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h @@ -36,6 +36,7 @@ class RigActiveCellInfo : public cvf::Object size_t globalCellCount() const; size_t globalActiveCellCount() const; size_t globalCellResultCount() const; + bool isCoarseningActive() const; bool isActive(size_t globalCellIndex) const; size_t cellResultIndex(size_t globalCellIndex) const; From bd528cc8d2bf17dcc77b1cebaf18ac36034d1843 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 3 Apr 2014 11:09:42 +0200 Subject: [PATCH 045/130] Updated use of buffer read --- OctavePlugin/riGetActiveCellInfo.cpp | 48 +++++++--------------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/OctavePlugin/riGetActiveCellInfo.cpp b/OctavePlugin/riGetActiveCellInfo.cpp index 824134e0f7..a7213a3697 100644 --- a/OctavePlugin/riGetActiveCellInfo.cpp +++ b/OctavePlugin/riGetActiveCellInfo.cpp @@ -1,7 +1,10 @@ #include +#include + #include #include "riSettings.h" +#include "riSocketTools.h" void getActiveCellInfo(int32NDArray& activeCellInfo, const QString &hostName, quint16 port, const qint64& caseId, const QString& porosityModel) @@ -43,59 +46,32 @@ void getActiveCellInfo(int32NDArray& activeCellInfo, const QString &hostName, qu // Read timestep count and blocksize quint64 columnCount; - quint64 byteCount; + quint64 byteCountForOneTimestep; size_t activeCellCount; socketStream >> columnCount; - socketStream >> byteCount; + socketStream >> byteCountForOneTimestep; - activeCellCount = byteCount / sizeof(qint32); + activeCellCount = byteCountForOneTimestep / sizeof(qint32); dim_vector dv (2, 1); dv(0) = activeCellCount; dv(1) = columnCount; activeCellInfo.resize(dv); - if (!(byteCount && columnCount)) + if (!(byteCountForOneTimestep && columnCount)) { error ("Could not find the requested data in ResInsight"); return; } - // Wait for available data for each column, then read data for each column - for (size_t tIdx = 0; tIdx < columnCount; ++tIdx) + qint32* internalMatrixData = (qint32*)activeCellInfo.fortran_vec()->mex_get_data(); + QStringList errorMessages; + if (!readBlockData(socket, (char*)(internalMatrixData), columnCount * byteCountForOneTimestep, errorMessages)) { - while (socket.bytesAvailable() < (int)byteCount) - { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) - { - QString errorMsg = QString("Waiting for column number: %1 of %2: %3").arg(tIdx).arg(columnCount).arg(socket.errorString()); - - error(errorMsg.toLatin1().data()); - octave_stdout << "Active cells: " << activeCellCount << ", Columns: " << columnCount << std::endl; - return ; - } - OCTAVE_QUIT; - } - - qint64 bytesRead = 0; - qint32* internalMatrixData = (qint32*)activeCellInfo.fortran_vec()->mex_get_data(); - -#if 1 // Use raw data transfer. Faster. - bytesRead = socket.read((char*)(internalMatrixData + tIdx * activeCellCount), byteCount); -#else - for (size_t cIdx = 0; cIdx < activeCellCount; ++cIdx) - { - socketStream >> internalMatrixData[tIdx * activeCellCount + cIdx]; - - if (socketStream.status() == QDataStream::Ok) bytesRead += sizeof(int); - } -#endif - - if ((int)byteCount != bytesRead) + for (int i = 0; i < errorMessages.size(); i++) { - error("Could not read binary double data properly from socket"); - octave_stdout << "Active cells: " << activeCellCount << ", Columns: " << columnCount << std::endl; + error(errorMessages[i].toLatin1().data()); } OCTAVE_QUIT; From 0562f92585f6b420caf1f6cf9d88c5c24083e8b7 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 3 Apr 2014 11:56:01 +0200 Subject: [PATCH 046/130] Updated riGetGridProperty --- .../RiaPropertyDataCommands.cpp | 57 +++--------- OctavePlugin/riGetGridProperty.cpp | 92 ++----------------- 2 files changed, 22 insertions(+), 127 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index 00210e4e21..87cf148f7c 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -306,60 +306,27 @@ class RiaGetGridProperty: public RiaSocketCommand quint64 timestepCount = (quint64)requestedTimesteps.size(); socketStream << timestepCount; - size_t valueIdx = 0; - cvf::Timer timer; - - if (RiaApplication::instance()->preferences()->useStreamTransfer()) + for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { - for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) + cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); + if (cellCenterDataAccessObject.isNull()) { - cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); - if (cellCenterDataAccessObject.isNull()) - { - continue; - } - - for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) - { - double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); - if (cellValue == HUGE_VAL) - { - cellValue = 0.0; - } - - socketStream << cellValue; - } + continue; } - } - else - { - for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) + std::vector values(rigGrid->cellCount()); + for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) { - cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); - if (cellCenterDataAccessObject.isNull()) - { - continue; - } - - std::vector values(rigGrid->cellCount()); - for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) + double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); + if (cellValue == HUGE_VAL) { - double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); - if (cellValue == HUGE_VAL) - { - cellValue = 0.0; - } - values[valueIdx++] = cellValue; + cellValue = 0.0; } - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), values.size() * sizeof(double)); + values[cellIdx] = cellValue; } - } - double totalTimeMS = timer.time() * 1000.0; - QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); - - server->errorMessageDialog()->showMessage(resultInfo); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), values.size() * sizeof(double)); + } return true; } diff --git a/OctavePlugin/riGetGridProperty.cpp b/OctavePlugin/riGetGridProperty.cpp index 3b1fbc589f..e477cd767a 100644 --- a/OctavePlugin/riGetGridProperty.cpp +++ b/OctavePlugin/riGetGridProperty.cpp @@ -1,6 +1,11 @@ #include +#include + #include + #include "riSettings.h" +#include "riSocketTools.h" + void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 serverPort, const int& caseId, int gridIdx, QString propertyName, const int32NDArray& requestedTimeSteps, QString porosityModel) @@ -61,8 +66,6 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 totalByteCount = cellCountI*cellCountJ*cellCountK*timestepCount*sizeof(double); - qint64 timestepByteCount = cellCountI*cellCountJ*cellCountK*sizeof(double); - if (!(totalByteCount)) { error ("Could not find the requested data in ResInsight"); @@ -78,93 +81,18 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 propertyFrames.resize(dv); - -#if 1 - // Wait for available data for each timestep, then read data for each timestep - - qint64 totalBytesRead = 0; - - for (size_t tIdx = 0; tIdx < timestepCount; ++tIdx) + double* internalMatrixData = propertyFrames.fortran_vec(); + QStringList errorMessages; + if (!readBlockData(socket, (char*)(internalMatrixData), totalByteCount, errorMessages)) { - qint64 bytesAvailable = socket.bytesAvailable() ; - - while ( bytesAvailable < (qint64)timestepByteCount) + for (int i = 0; i < errorMessages.size(); i++) { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) - { - error((("Waiting for timestep data number: ") + QString::number(tIdx)+ ": " + socket.errorString()).toLatin1().data()); - octave_stdout << "Cellcount: " << cellCountI*cellCountJ*cellCountK << ", Timesteps: " << timestepCount << std::endl; - return ; - } - - bytesAvailable = socket.bytesAvailable(); - - OCTAVE_QUIT; + error(errorMessages[i].toLatin1().data()); } - qint64 bytesRead = 0; - double * internalMatrixData = propertyFrames.fortran_vec(); - - // Raw data transfer. Faster. Not possible when dealing with coarsening - bytesRead = socket.read(((char*)(internalMatrixData)) + tIdx * timestepByteCount, timestepByteCount); - - if ((qint64)timestepByteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - octave_stdout << "Cellcount: " << cellCountI*cellCountJ*cellCountK << ", Timesteps count: " << timestepCount << std::endl; - octave_stdout << "Timestep : " << tIdx << std::endl; - } - - totalBytesRead += bytesRead; - - OCTAVE_QUIT; - } - - if ((qint64)totalByteCount != totalBytesRead) - { - error("Could not read binary double data properly from socket"); - } - - #else - - // Wait for available data - qint64 bytesAvailable = socket.bytesAvailable() ; - - while (bytesAvailable < (qint64)totalByteCount) - { - octave_stdout << "Waiting for data. Has : " << bytesAvailable << " Needs :" << totalByteCount << std::endl; - if (!socket.waitForReadyRead(riOctavePlugin::shortTimeOutMilliSecs)) - { - //error(("Waiting for data : " + socket.errorString()).toLatin1().data()); - //return ; - } - - bytesAvailable = socket.bytesAvailable() ; OCTAVE_QUIT; } - qint64 bytesRead = 0; - double * internalMatrixData = propertyFrames.fortran_vec(); - -#if 0 - - char* dataBuffer = new char[totalByteCount]; - bytesRead = socket.read(dataBuffer, totalByteCount); - - -#else - - // Raw data transfer. Faster. - bytesRead = socket.read((char*)(internalMatrixData ), totalByteCount); -#endif - - - if ((qint64)totalByteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - } - -#endif QString tmp = QString("riGetGridProperty : Read %1").arg(propertyName); if (caseId < 0) From 7b68c3cb6b7b7fefc4d6a448db1d05218a00223f Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 14 Apr 2014 10:24:15 +0200 Subject: [PATCH 047/130] Fix after merge conflicts take two --- ApplicationCode/Application/RiaPreferences.cpp | 4 +--- ApplicationCode/Application/RiaPreferences.h | 3 --- ApplicationCode/ProjectDataModel/CMakeLists_files.cmake | 6 ------ ApplicationCode/ProjectDataModel/RimDefines.h | 7 ------- ApplicationCode/ProjectDataModel/RimResultCase.cpp | 3 --- .../ReservoirDataModel/RigReservoirBuilderMock.cpp | 9 +++------ Fwk/AppFwk/cafUserInterface/CMakeLists.txt | 5 ----- 7 files changed, 4 insertions(+), 33 deletions(-) diff --git a/ApplicationCode/Application/RiaPreferences.cpp b/ApplicationCode/Application/RiaPreferences.cpp index abe04fa30f..b1d94b514c 100644 --- a/ApplicationCode/Application/RiaPreferences.cpp +++ b/ApplicationCode/Application/RiaPreferences.cpp @@ -59,10 +59,8 @@ RiaPreferences::RiaPreferences(void) CAF_PDM_InitField(&autocomputeSOIL, "autocomputeSOIL", true, "SOIL", "", "SOIL = 1.0 - SGAS - SWAT", ""); CAF_PDM_InitField(&autocomputeDepthRelatedProperties,"autocomputeDepth", true, "DEPTH related properties", "", "DEPTH, DX, DY, DZ, TOP, BOTTOM", ""); -<<<<<<< HEAD CAF_PDM_InitField(&readFaultData, "readFaultData", true, "Read fault data", "", "", ""); -======= ->>>>>>> 770f70680345d00c4b6c828e1e36f3f12000a390 + CAF_PDM_InitField(&useStreamTransfer, "useStreamTransfer", true, "Use stream transfer to Octave", "", "", ""); CAF_PDM_InitField(&blockSize, "blockSize", 10000, "blockSize", "", "", ""); } diff --git a/ApplicationCode/Application/RiaPreferences.h b/ApplicationCode/Application/RiaPreferences.h index 978c4b144e..785eccf6d6 100644 --- a/ApplicationCode/Application/RiaPreferences.h +++ b/ApplicationCode/Application/RiaPreferences.h @@ -63,9 +63,6 @@ class RiaPreferences : public caf::PdmObject caf::PdmField useStreamTransfer; caf::PdmField blockSize; - caf::PdmField useStreamTransfer; - caf::PdmField blockSize; - protected: virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); diff --git a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake index 01c0213347..4e0d185f37 100644 --- a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake @@ -44,11 +44,8 @@ ${CEE_CURRENT_LIST_DIR}RimStatisticsCaseEvaluator.h ${CEE_CURRENT_LIST_DIR}RimMimeData.h ${CEE_CURRENT_LIST_DIR}RimCommandObject.h ${CEE_CURRENT_LIST_DIR}RimTools.h -<<<<<<< HEAD ${CEE_CURRENT_LIST_DIR}RimFault.h ${CEE_CURRENT_LIST_DIR}RimFaultCollection.h -======= ->>>>>>> 770f70680345d00c4b6c828e1e36f3f12000a390 ${CEE_CURRENT_LIST_DIR}RimMockModelSettings.h ) @@ -92,11 +89,8 @@ ${CEE_CURRENT_LIST_DIR}RimStatisticsCaseEvaluator.cpp ${CEE_CURRENT_LIST_DIR}RimMimeData.cpp ${CEE_CURRENT_LIST_DIR}RimCommandObject.cpp ${CEE_CURRENT_LIST_DIR}RimTools.cpp -<<<<<<< HEAD ${CEE_CURRENT_LIST_DIR}RimFault.cpp ${CEE_CURRENT_LIST_DIR}RimFaultCollection.cpp -======= ->>>>>>> 770f70680345d00c4b6c828e1e36f3f12000a390 ${CEE_CURRENT_LIST_DIR}RimMockModelSettings.cpp ) diff --git a/ApplicationCode/ProjectDataModel/RimDefines.h b/ApplicationCode/ProjectDataModel/RimDefines.h index 1398300156..0dd82175f1 100644 --- a/ApplicationCode/ProjectDataModel/RimDefines.h +++ b/ApplicationCode/ProjectDataModel/RimDefines.h @@ -40,11 +40,8 @@ class RimDefines }; static QString undefinedResultName() { return "None"; } -<<<<<<< HEAD static QString undefinedGridFaultName() { return "Undefined grid faults"; } static QString combinedTransmissibilityResultName() { return "TRANSXYZ"; } -======= ->>>>>>> 770f70680345d00c4b6c828e1e36f3f12000a390 // Mock model text identifiers @@ -54,9 +51,5 @@ class RimDefines static QString mockModelCustomized() { return "Result Mock Debug Model Customized"; } static QString mockModelBasicInputCase() { return "Input Mock Debug Model Simple"; } -<<<<<<< HEAD -======= - ->>>>>>> 770f70680345d00c4b6c828e1e36f3f12000a390 }; diff --git a/ApplicationCode/ProjectDataModel/RimResultCase.cpp b/ApplicationCode/ProjectDataModel/RimResultCase.cpp index 66c43e6046..a392121b5f 100644 --- a/ApplicationCode/ProjectDataModel/RimResultCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultCase.cpp @@ -49,10 +49,7 @@ #include "Rim3dOverlayInfoConfig.h" #include "RimOilField.h" #include "RimAnalysisModels.h" -<<<<<<< HEAD #include "RiaPreferences.h" -======= ->>>>>>> 770f70680345d00c4b6c828e1e36f3f12000a390 #include "RimMockModelSettings.h" CAF_PDM_SOURCE_INIT(RimResultCase, "EclipseCase"); diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp index 715c489490..221bb9db1b 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp @@ -253,11 +253,8 @@ void RigReservoirBuilderMock::populateReservoir(RigCaseData* eclipseCase) { addWellData(eclipseCase, eclipseCase->mainGrid()); } -<<<<<<< HEAD addFaults(eclipseCase); -======= ->>>>>>> 770f70680345d00c4b6c828e1e36f3f12000a390 // Set all cells active RigActiveCellInfo* activeCellInfo = eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); @@ -495,7 +492,6 @@ void RigReservoirBuilderMock::addWellData(RigCaseData* eclipseCase, RigGridBase* //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -<<<<<<< HEAD void RigReservoirBuilderMock::addFaults(RigCaseData* eclipseCase) { if (!eclipseCase) return; @@ -533,8 +529,9 @@ void RigReservoirBuilderMock::addFaults(RigCaseData* eclipseCase) grid->setFaults(faults); } -======= ->>>>>>> 770f70680345d00c4b6c828e1e36f3f12000a390 +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- void RigReservoirBuilderMock::enableWellData(bool enableWellData) { m_enableWellData = false; diff --git a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt index a732521f1d..b210e4a322 100644 --- a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt +++ b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt @@ -38,13 +38,8 @@ endif() add_library( ${PROJECT_NAME} -<<<<<<< HEAD cafAboutDialog.cpp cafAboutDialog.h -======= - cafBasicAboutDialog.cpp - cafBasicAboutDialog.h ->>>>>>> 770f70680345d00c4b6c828e1e36f3f12000a390 cafPdmSettings.cpp cafPdmUiCheckBoxEditor.cpp cafPdmUiCheckBoxEditor.h From 0f01703ac3202c8a0886e079e481ef1f44159db2 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 14 Apr 2014 14:36:47 +0200 Subject: [PATCH 048/130] Added socket data transfer Added one common class used to transfer data using socket. This class is used both from the Octave plugins and from the socket server code in ResInsight --- ApplicationCode/CMakeLists.txt | 3 + .../SocketInterface/RiaSocketDataTransfer.cpp | 102 ++++++++++++++++++ .../SocketInterface/RiaSocketDataTransfer.h | 36 +++++++ .../SocketInterface/RiaSocketTools.cpp | 84 +++------------ .../SocketInterface/RiaSocketTools.h | 1 - OctavePlugin/CMakeLists.txt | 6 +- 6 files changed, 156 insertions(+), 76 deletions(-) create mode 100644 ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp create mode 100644 ApplicationCode/SocketInterface/RiaSocketDataTransfer.h diff --git a/ApplicationCode/CMakeLists.txt b/ApplicationCode/CMakeLists.txt index 29c2db248b..d4e7e4113f 100644 --- a/ApplicationCode/CMakeLists.txt +++ b/ApplicationCode/CMakeLists.txt @@ -58,6 +58,7 @@ set( SOCKET_INTERFACE_FILES SocketInterface/RiaPropertyDataCommands.cpp SocketInterface/RiaWellDataCommands.cpp SocketInterface/RiaSocketTools.cpp + SocketInterface/RiaSocketDataTransfer.cpp ) @@ -153,6 +154,8 @@ list( REMOVE_ITEM RAW_SOURCES Application/RiaImageCompareReporter.cpp Application/RiaRegressionTest.cpp + SocketInterface/RiaSocketDataTransfer.cpp + FileInterface/RifEclipseInputFileTools.cpp FileInterface/RifEclipseOutputFileTools.cpp FileInterface/RifEclipseRestartFilesetAccess.cpp diff --git a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp new file mode 100644 index 0000000000..c49ff5fa1f --- /dev/null +++ b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp @@ -0,0 +1,102 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA, Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaSocketDataTransfer.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiaSocketDataTransfer::writeBlockDataToSocket(QTcpSocket* socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages) +{ + quint64 bytesWritten = 0; + int blockCount = 0; + + quint64 maxBlockSize = doubleValueCountInBlock() * sizeof(double); + + while (bytesWritten < bytesToWrite) + { + quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize); + + qint64 actuallyBytesWritten = socket->write(data + bytesWritten, byteCountToWrite); + if (actuallyBytesWritten < 0) + { + errorMessages.push_back("Error detected when writing data, error string from socket"); + errorMessages.push_back(socket->errorString()); + + return false; + } + + bytesWritten += actuallyBytesWritten; + + blockCount++; + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiaSocketDataTransfer::readBlockDataFromSocket(QTcpSocket* socket, char* data, quint64 bytesToRead, QStringList& errorMessages) +{ + quint64 bytesRead = 0; + int blockCount = 0; + + quint64 maxBlockSize = doubleValueCountInBlock() * sizeof(double); + + while (bytesRead < bytesToRead) + { + if (socket->bytesAvailable()) + { + quint64 byteCountToRead = qMin(bytesToRead - bytesRead, maxBlockSize); + + qint64 actuallyBytesRead = socket->read(data + bytesRead, byteCountToRead); + if (actuallyBytesRead < 0) + { + errorMessages.push_back("Error detected when reading data, error string from socket"); + errorMessages.push_back(socket->errorString()); + + return false; + } + + bytesRead += actuallyBytesRead; + blockCount++; + } + else + { + if (!socket->waitForReadyRead()) + { + errorMessages.push_back("Waited for data for %1 milli seconds."); + errorMessages.push_back(socket->errorString()); + + return false; + } + } + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RiaSocketDataTransfer::doubleValueCountInBlock() +{ + return 2000; +} + diff --git a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.h b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.h new file mode 100644 index 0000000000..06ae14b379 --- /dev/null +++ b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.h @@ -0,0 +1,36 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA, Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include +#include + +//================================================================================================== +/// Utility class used for transfer of data using QTcpSocket +/// +/// As the compile configuration for octave plugins is quite complex, +// the octave plugins includes the cpp-file to be able to compile only one file per plugin +//================================================================================================== +class RiaSocketDataTransfer +{ +public: + static size_t doubleValueCountInBlock(); + +public: + static bool writeBlockDataToSocket(QTcpSocket* socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages); + static bool readBlockDataFromSocket(QTcpSocket* socket, char* data, quint64 bytesToRead, QStringList& errorMessages); +}; diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.cpp b/ApplicationCode/SocketInterface/RiaSocketTools.cpp index 64cc8e0c11..86f7ce6086 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketTools.cpp @@ -38,8 +38,9 @@ #include "RimInputPropertyCollection.h" -#include +#include "RiaSocketDataTransfer.h" +#include //-------------------------------------------------------------------------------------------------- /// @@ -104,89 +105,28 @@ void RiaSocketTools::getCaseInfoFromCase(RimCase* rimCase, qint64& caseId, QStri } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- bool RiaSocketTools::writeBlockData(RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite) { cvf::Timer timer; - quint64 bytesWritten = 0; - int blockCount = 0; + QStringList errorMessages; + bool writeSucceded = RiaSocketDataTransfer::writeBlockDataToSocket(socket, data, bytesToWrite, errorMessages); - quint64 maxBlockSize = RiaApplication::instance()->preferences()->blockSize(); - - - while (bytesWritten < bytesToWrite) + if (server) { - quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize); - - qint64 actuallyBytesWritten = socket->write(data + bytesWritten, byteCountToWrite); - if (actuallyBytesWritten < 0) + for (int i = 0; i < errorMessages.size(); i++) { - if (server) - { - QString errorMessage = "Error detected when writing data, error string from socket : \n" + socket->errorString(); - - server->errorMessageDialog()->showMessage(errorMessage); - } - - return false; + server->errorMessageDialog()->showMessage(errorMessages[i]); } - bytesWritten += actuallyBytesWritten; - - blockCount++; - } - - if (server) - { double totalTimeMS = timer.time() * 1000.0; - QString resultInfo = QString("Total time '%1 ms'\nTotal bytes written . %2\nNumber of blocks : %3\nBlock size : %4").arg(totalTimeMS).arg(bytesWritten).arg(blockCount).arg(maxBlockSize); + QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); server->errorMessageDialog()->showMessage(resultInfo); } - return true; + return writeSucceded; } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RiaSocketTools::readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages) -{ - quint64 bytesRead = 0; - int blockCount = 0; - - quint64 maxBlockSize = RiaApplication::instance()->preferences()->blockSize(); - - while (bytesRead < bytesToRead) - { - if (socket.bytesAvailable()) - { - quint64 byteCountToRead = qMin(bytesToRead - bytesRead, maxBlockSize); - - qint64 actuallyBytesRead = socket.read(data + bytesRead, byteCountToRead); - if (actuallyBytesRead < 0) - { - errorMessages.push_back("Error detected when writing data, error string from socket"); - errorMessages.push_back(socket.errorString()); - - return false; - } - - bytesRead += actuallyBytesRead; - blockCount++; - } - else - { - if (!socket.waitForReadyRead()) - { - errorMessages.push_back("Waited for data for %1 milli seconds."); - errorMessages.push_back(socket.errorString()); - - return false; - } - } - } - - return true; -} - diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.h b/ApplicationCode/SocketInterface/RiaSocketTools.h index 5a24731237..b331799e2e 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.h +++ b/ApplicationCode/SocketInterface/RiaSocketTools.h @@ -28,5 +28,4 @@ class RiaSocketTools static void getCaseInfoFromCase(RimCase* rimCase, qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId); static bool writeBlockData(RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite); - static bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages); }; diff --git a/OctavePlugin/CMakeLists.txt b/OctavePlugin/CMakeLists.txt index 7a11e18ab9..80d714789f 100644 --- a/OctavePlugin/CMakeLists.txt +++ b/OctavePlugin/CMakeLists.txt @@ -88,7 +88,7 @@ if (RESINSIGHT_OCTAVE_PLUGIN_QMAKE AND RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE) OUTPUT "${octFileName}" COMMAND call "\"%VS100COMNTOOLS%../../VC/vcvarsall.bat\"" x86 COMMAND ${CMAKE_COMMAND} ARGS -E chdir ${RESINSIGHT_OCTAVE_BIN_DIR} ${RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE} -I${OCTAVE_QT_QTNETWORK_INCLUDE_DIR} - -I${OCTAVE_QT_QTCORE_INCLUDE_DIR} -I${OCTAVE_QT_INCLUDE_DIR} ${RPATH_COMMAND} + -I${OCTAVE_QT_QTCORE_INCLUDE_DIR} -I${OCTAVE_QT_INCLUDE_DIR} -I${ResInsight_SOURCE_DIR}/ApplicationCode/SocketInterface ${RPATH_COMMAND} -L${OCTAVE_QT_LIBRARY_DIR} -lQtCore${QT_LIBRARY_POSTFIX} -lQtNetwork${QT_LIBRARY_POSTFIX} -o "${octFileName}" "${srcFileName}" DEPENDS "${srcFileName}" COMMENT "===> 32-bit x86 VS2010 : Generating ${octFileName}" @@ -97,7 +97,7 @@ if (RESINSIGHT_OCTAVE_PLUGIN_QMAKE AND RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE) add_custom_command( OUTPUT "${octFileName}" COMMAND ${CMAKE_COMMAND} ARGS -E chdir ${RESINSIGHT_OCTAVE_BIN_DIR} ${RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE} -I${OCTAVE_QT_QTNETWORK_INCLUDE_DIR} - -I${OCTAVE_QT_QTCORE_INCLUDE_DIR} -I${OCTAVE_QT_INCLUDE_DIR} ${RPATH_COMMAND} + -I${OCTAVE_QT_QTCORE_INCLUDE_DIR} -I${OCTAVE_QT_INCLUDE_DIR} -I${ResInsight_SOURCE_DIR}/ApplicationCode/SocketInterface ${RPATH_COMMAND} -L${OCTAVE_QT_LIBRARY_DIR} -lQtCore${QT_LIBRARY_POSTFIX} -lQtNetwork${QT_LIBRARY_POSTFIX} -o "${octFileName}" "${srcFileName}" DEPENDS "${srcFileName}" COMMENT "===> Generating ${octFileName}" @@ -107,7 +107,7 @@ if (RESINSIGHT_OCTAVE_PLUGIN_QMAKE AND RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE) add_custom_command( OUTPUT "${octFileName}" COMMAND OCTAVE_HOME=${OCTAVE_HOME} ${RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE} - -I${OCTAVE_QT_QTNETWORK_INCLUDE_DIR} -I${OCTAVE_QT_QTCORE_INCLUDE_DIR} -I${OCTAVE_QT_INCLUDE_DIR} ${RPATH_COMMAND} + -I${OCTAVE_QT_QTNETWORK_INCLUDE_DIR} -I${OCTAVE_QT_QTCORE_INCLUDE_DIR} -I${OCTAVE_QT_INCLUDE_DIR} -I${ResInsight_SOURCE_DIR}/ApplicationCode/SocketInterface ${RPATH_COMMAND} -L${OCTAVE_QT_LIBRARY_DIR} -lQtCore -lQtNetwork -o "${octFileName}" "${srcFileName}" DEPENDS "${srcFileName}" COMMENT "===> Generating ${octFileName}" From 922d76cd9128ee0bc50910055dd2c57b0b77e116 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 15 Apr 2014 08:51:18 +0200 Subject: [PATCH 049/130] Set atomics workaround if needed --- CMakeLists.txt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f551c8beb2..590b6d0b72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,9 +97,19 @@ find_package( OpenGL ) ################################################################################ # Allow use of non-threadsafe reference counter in cvf::Object on systems with no atomics support -option(RESINSIGHT_WORKAROUND_ON_SYSTEMS_WITHOUT_ATOMICS "Allow use of non-threadsafe reference counter on systems with no atomics support" OFF) -if (RESINSIGHT_WORKAROUND_ON_SYSTEMS_WITHOUT_ATOMICS) - add_definitions(-DCVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS) +if (CMAKE_COMPILER_IS_GNUCC) + + check_c_source_compiles("int main(int argc, char **argv) { + int a; + __sync_add_and_fetch(&a, 1); + __sync_fetch_and_add(&a, 1); + __sync_sub_and_fetch(&a, 1); + __sync_fetch_and_sub(&a, 1); }" HAVE_GCC_ATOMICS) + + if (NOT HAVE_GCC_ATOMITCS) + add_definitions(-DCVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS) + endif() + endif() add_subdirectory(${VIZ_MODULES_FOLDER_NAME}/LibCore) From 74d7ba276ec7a82e04faf554cc1c7c39455f6141 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 15 Apr 2014 09:48:32 +0200 Subject: [PATCH 050/130] Test if variable is defined before executing GCC test --- CMakeLists.txt | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 590b6d0b72..c32423b2a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,14 +99,19 @@ find_package( OpenGL ) # Allow use of non-threadsafe reference counter in cvf::Object on systems with no atomics support if (CMAKE_COMPILER_IS_GNUCC) - check_c_source_compiles("int main(int argc, char **argv) { - int a; - __sync_add_and_fetch(&a, 1); - __sync_fetch_and_add(&a, 1); - __sync_sub_and_fetch(&a, 1); - __sync_fetch_and_sub(&a, 1); }" HAVE_GCC_ATOMICS) + if (NOT DEFINED HAVE_GCC_ATOMICS) + check_c_source_compiles("int main(int argc, char **argv) { + int a; + __sync_add_and_fetch(&a, 1); + __sync_fetch_and_add(&a, 1); + __sync_sub_and_fetch(&a, 1); + __sync_fetch_and_sub(&a, 1); }" HAVE_GCC_ATOMICS) + endif() - if (NOT HAVE_GCC_ATOMITCS) + if (HAVE_GCC_ATOMICS) + message("Atomics supported") + else() + message("Atomics not supported") add_definitions(-DCVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS) endif() From bf9ecc7c5f51a63b2a3106cba697d81e7a8eb4fc Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 15 Apr 2014 11:50:04 +0200 Subject: [PATCH 051/130] Changed how synchronization functions are detected --- CMakeLists.txt | 12 ++++++------ Fwk/VizFwk/LibCore/cvfAtomicCounter.cpp | 2 +- Fwk/VizFwk/LibCore/cvfAtomicCounter.h | 7 +------ Fwk/VizFwk/LibCore/cvfObject.h | 16 +++++++--------- 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c32423b2a5..a41fddb4da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,20 +99,20 @@ find_package( OpenGL ) # Allow use of non-threadsafe reference counter in cvf::Object on systems with no atomics support if (CMAKE_COMPILER_IS_GNUCC) - if (NOT DEFINED HAVE_GCC_ATOMICS) + if (NOT DEFINED HAVE_GCC_SYNC_FUNCTIONS) check_c_source_compiles("int main(int argc, char **argv) { int a; __sync_add_and_fetch(&a, 1); __sync_fetch_and_add(&a, 1); __sync_sub_and_fetch(&a, 1); - __sync_fetch_and_sub(&a, 1); }" HAVE_GCC_ATOMICS) + __sync_fetch_and_sub(&a, 1); }" HAVE_GCC_SYNC_FUNCTIONS) endif() - if (HAVE_GCC_ATOMICS) - message("Atomics supported") + if (HAVE_GCC_SYNC_FUNCTIONS) + message("GCC synchronization functions detected") else() - message("Atomics not supported") - add_definitions(-DCVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS) + message("GCC synchronization functions NOT detected, fallback to non threadsafe reference counting") + add_definitions(-DCVF_USE_NON_THREADSAFE_REFERENCE_COUNT) endif() endif() diff --git a/Fwk/VizFwk/LibCore/cvfAtomicCounter.cpp b/Fwk/VizFwk/LibCore/cvfAtomicCounter.cpp index 4d1768f0fd..2c6953eb09 100644 --- a/Fwk/VizFwk/LibCore/cvfAtomicCounter.cpp +++ b/Fwk/VizFwk/LibCore/cvfAtomicCounter.cpp @@ -141,7 +141,7 @@ int AtomicCounter::operator -- (int) // postfix } -#elif defined(CVF_HAVE_GCC_ATOMICS) +#elif defined(CVF_GCC_DEFINED) AtomicCounter::AtomicCounter(int initialValue) diff --git a/Fwk/VizFwk/LibCore/cvfAtomicCounter.h b/Fwk/VizFwk/LibCore/cvfAtomicCounter.h index eef1eb38f7..424e822b1a 100644 --- a/Fwk/VizFwk/LibCore/cvfAtomicCounter.h +++ b/Fwk/VizFwk/LibCore/cvfAtomicCounter.h @@ -45,13 +45,8 @@ #include #define CVF_ATOMIC_COUNTER_CLASS_EXISTS #elif defined __GNUC__ - #if (CVF_GCC_VER >= 40200) && (defined(__x86_64__) || defined(__i386__)) - #define CVF_HAVE_GCC_ATOMICS + #define CVF_GCC_DEFINED #define CVF_ATOMIC_COUNTER_CLASS_EXISTS - #elif (CVF_GCC_VER >= 40300) - #define CVF_HAVE_GCC_ATOMICS - #define CVF_ATOMIC_COUNTER_CLASS_EXISTS - #endif #endif #if defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS) diff --git a/Fwk/VizFwk/LibCore/cvfObject.h b/Fwk/VizFwk/LibCore/cvfObject.h index 264cab83af..b048228b0f 100644 --- a/Fwk/VizFwk/LibCore/cvfObject.h +++ b/Fwk/VizFwk/LibCore/cvfObject.h @@ -43,12 +43,8 @@ #include "cvfAtomicCounter.h" -#if defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS) && defined(CVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS) -#error Two mutually exclusive defines detected : CVF_ATOMIC_COUNTER_CLASS_EXISTS && CVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS -#endif - -#if !defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS) && !defined(CVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS) -#error No support for atomics. Define CVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS to be able to compile +#if !defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS) && !defined(CVF_USE_NON_THREADSAFE_REFERENCE_COUNT) +#error No support for atomics. Define CVF_USE_NON_THREADSAFE_REFERENCE_COUNT to be able to compile #endif namespace cvf { @@ -75,10 +71,12 @@ class Object private: -#if defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS) - mutable AtomicCounter m_refCount; -#elif defined(CVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS) +#if defined(CVF_USE_NON_THREADSAFE_REFERENCE_COUNT) mutable int m_refCount; +#elif defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS) + mutable AtomicCounter m_refCount; +#else + #error No support for atomics. Define CVF_USE_NON_THREADSAFE_REFERENCE_COUNT to be able to compile #endif From 8ea418272d7241469ed5bcab8fd6f84bc0a36a1e Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 15 Apr 2014 13:04:57 +0200 Subject: [PATCH 052/130] Fixed invalid assert --- ApplicationCode/SocketInterface/RiaGeometryCommands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp index 2ca72a655d..c76bc690ae 100644 --- a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp @@ -276,7 +276,7 @@ class RiaGetCellCorners : public RiaSocketCommand } } - CVF_ASSERT(valueIndex, cellCount); + CVF_ASSERT(valueIndex == cellCount); RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); } From b4821ed7a3baf58aed653c93367da5c7fe858d22 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 15 Apr 2014 13:40:53 +0200 Subject: [PATCH 053/130] Use block transfer for data transfer of cell properties --- .../RiaPropertyDataCommands.cpp | 98 ++++++++++++------- .../SocketInterface/RiaSocketDataTransfer.cpp | 13 ++- .../SocketInterface/RiaSocketTools.cpp | 8 +- OctavePlugin/CMakeLists.txt | 36 +++---- OctavePlugin/riGetActiveCellProperty.cpp | 45 +++------ OctavePlugin/riGetGridProperty.cpp | 6 +- OctavePlugin/riSetActiveCellProperty.cpp | 32 +++--- OctavePlugin/riSetGridProperty.cpp | 52 +++++----- OctavePlugin/riSocketTools.h | 4 +- 9 files changed, 154 insertions(+), 140 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index 87cf148f7c..385ee7603d 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -42,6 +42,7 @@ #include #include "RiaApplication.h" #include "RiaPreferences.h" +#include "RiaSocketDataTransfer.h" //-------------------------------------------------------------------------------------------------- @@ -145,6 +146,9 @@ class RiaGetActiveCellProperty: public RiaSocketCommand socketStream << timestepByteCount ; // Then write the data. + size_t valueCount = RiaSocketDataTransfer::doubleValueCountInBlock(); + std::vector values(valueCount); + size_t valueIndex = 0; size_t globalCellCount = activeInfo->globalCellCount(); for (size_t tIdx = 0; tIdx < requestedTimesteps.size(); ++tIdx) @@ -156,37 +160,34 @@ class RiaGetActiveCellProperty: public RiaSocketCommand { if (resultIdx < scalarResultFrames->at(requestedTimesteps[tIdx]).size()) { - socketStream << scalarResultFrames->at(requestedTimesteps[tIdx])[resultIdx]; + values[valueIndex] = scalarResultFrames->at(requestedTimesteps[tIdx])[resultIdx]; } else { - socketStream << HUGE_VAL; + values[valueIndex] = HUGE_VAL; + } + + valueIndex++; + if (valueIndex >= valueCount) + { + if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double))) + { + return false; + } + + valueIndex = 0; } } } } -#if 0 - // This aproach is faster but does not handle coarsening - size_t timestepResultCount = scalarResultFrames->front().size(); - quint64 timestepByteCount = (quint64)(timestepResultCount*sizeof(double)); - socketStream << timestepByteCount ; - - // Then write the data. - for (size_t tIdx = 0; tIdx < requestedTimesteps.size(); ++tIdx) + // Write remaining data + if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double))) { -#if 1 // Write data as raw bytes, fast but does not handle byteswapping - server->currentClient()->write((const char *)scalarResultFrames->at(requestedTimesteps[tIdx]).data(), timestepByteCount); // Raw print of data. Fast but no platform conversion -#else // Write data using QDataStream, does byteswapping for us. Must use QDataStream on client as well - for (size_t cIdx = 0; cIdx < scalarResultFrames->at(requestedTimesteps[tIdx]).size(); ++cIdx) - { - socketStream << scalarResultFrames->at(tIdx)[cIdx]; - } -#endif + return false; } -#endif - } + } return true; } }; @@ -314,7 +315,9 @@ class RiaGetGridProperty: public RiaSocketCommand continue; } - std::vector values(rigGrid->cellCount()); + size_t valueCount = RiaSocketDataTransfer::doubleValueCountInBlock(); + std::vector values(valueCount); + size_t valueIndex = 0; for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) { double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); @@ -322,10 +325,24 @@ class RiaGetGridProperty: public RiaSocketCommand { cellValue = 0.0; } - values[cellIdx] = cellValue; + values[valueIndex++] = cellValue; + + if (valueIndex >= valueCount) + { + if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double))) + { + return false; + } + + valueIndex = 0; + } } - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), values.size() * sizeof(double)); + // Write remaining data + if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double))) + { + return false; + } } return true; @@ -552,16 +569,18 @@ class RiaSetActiveCellProperty: public RiaSocketCommand internalMatrixData = m_scalarResultsToAdd->at(m_requestedTimesteps[m_currentTimeStepNumberToRead]).data(); } -#if 1 // Use raw data transfer. Faster. - bytesRead = currentClient->read((char*)(internalMatrixData), m_bytesPerTimeStepToRead); -#else - for (size_t cIdx = 0; cIdx < cellCountFromOctave; ++cIdx) + QStringList errorMessages; + if (!RiaSocketDataTransfer::readBlockDataFromSocket(currentClient, (char*)(internalMatrixData), m_bytesPerTimeStepToRead, errorMessages)) { - socketStream >> internalMatrixData[cIdx]; + for (int i = 0; i < errorMessages.size(); i++) + { + server->errorMessageDialog()->showMessage(errorMessages[i]); + } - if (socketStream.status() == QDataStream::Ok) bytesRead += sizeof(double); + currentClient->abort(); + return true; } -#endif + // Map data from active to result index based container ( Coarsening is active) if (isCoarseningActive) { @@ -576,12 +595,6 @@ class RiaSetActiveCellProperty: public RiaSocketCommand } } - if ((int)m_bytesPerTimeStepToRead != bytesRead) - { - server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + - RiaSocketServer::tr("Could not read binary double data properly from socket")); - } - ++m_currentTimeStepNumberToRead; } @@ -896,8 +909,17 @@ class RiaSetGridProperty : public RiaSocketCommand std::vector doubleValues(cellCountFromOctave); - qint64 bytesRead = currentClient->read((char*)(doubleValues.data()), m_bytesPerTimeStepToRead); - size_t doubleValueIndex = 0; + QStringList errorMessages; + if (!RiaSocketDataTransfer::readBlockDataFromSocket(currentClient, (char*)(doubleValues.data()), m_bytesPerTimeStepToRead, errorMessages)) + { + for (int i = 0; i < errorMessages.size(); i++) + { + server->errorMessageDialog()->showMessage(errorMessages[i]); + } + + currentClient->abort(); + return true; + } cvf::ref cellCenterDataAccessObject = m_currentReservoir->reservoirData()->dataAccessObject(grid, m_porosityModelEnum, m_requestedTimesteps[m_currentTimeStepNumberToRead], m_currentScalarIndex); diff --git a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp index c49ff5fa1f..8671f2e28d 100644 --- a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp @@ -18,6 +18,7 @@ #include "RiaSocketDataTransfer.h" + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -55,15 +56,12 @@ bool RiaSocketDataTransfer::writeBlockDataToSocket(QTcpSocket* socket, const cha bool RiaSocketDataTransfer::readBlockDataFromSocket(QTcpSocket* socket, char* data, quint64 bytesToRead, QStringList& errorMessages) { quint64 bytesRead = 0; - int blockCount = 0; - - quint64 maxBlockSize = doubleValueCountInBlock() * sizeof(double); while (bytesRead < bytesToRead) { if (socket->bytesAvailable()) { - quint64 byteCountToRead = qMin(bytesToRead - bytesRead, maxBlockSize); + quint64 byteCountToRead = bytesToRead - bytesRead; qint64 actuallyBytesRead = socket->read(data + bytesRead, byteCountToRead); if (actuallyBytesRead < 0) @@ -75,7 +73,6 @@ bool RiaSocketDataTransfer::readBlockDataFromSocket(QTcpSocket* socket, char* da } bytesRead += actuallyBytesRead; - blockCount++; } else { @@ -87,6 +84,12 @@ bool RiaSocketDataTransfer::readBlockDataFromSocket(QTcpSocket* socket, char* da return false; } } + +// Allow Octave process to end a long running Octave function +#ifdef octave_oct_h + OCTAVE_QUIT; +#endif + } return true; diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.cpp b/ApplicationCode/SocketInterface/RiaSocketTools.cpp index 86f7ce6086..967c0b43b4 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketTools.cpp @@ -122,10 +122,10 @@ bool RiaSocketTools::writeBlockData(RiaSocketServer* server, QTcpSocket* socket, server->errorMessageDialog()->showMessage(errorMessages[i]); } - double totalTimeMS = timer.time() * 1000.0; - QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); - - server->errorMessageDialog()->showMessage(resultInfo); +// double totalTimeMS = timer.time() * 1000.0; +// QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); +// +// server->errorMessageDialog()->showMessage(resultInfo); } return writeSucceded; diff --git a/OctavePlugin/CMakeLists.txt b/OctavePlugin/CMakeLists.txt index 80d714789f..a49a9e21d0 100644 --- a/OctavePlugin/CMakeLists.txt +++ b/OctavePlugin/CMakeLists.txt @@ -6,26 +6,26 @@ set(CPP_SOURCES riGetActiveCellProperty.cpp riSetActiveCellProperty.cpp - riGetActiveCellInfo.cpp - riGetMainGridDimensions.cpp - riGetCurrentCase.cpp - riGetCaseGroups.cpp - riGetSelectedCases.cpp - riGetCases.cpp - riGetTimeStepDates.cpp - riGetTimeStepDays.cpp - riGetGridDimensions.cpp - riGetCoarseningInfo.cpp - riGetCellCenters.cpp - riGetActiveCellCenters.cpp - riGetCellCorners.cpp - riGetActiveCellCorners.cpp +# riGetActiveCellInfo.cpp +# riGetMainGridDimensions.cpp +# riGetCurrentCase.cpp +# riGetCaseGroups.cpp +# riGetSelectedCases.cpp +# riGetCases.cpp +# riGetTimeStepDates.cpp +# riGetTimeStepDays.cpp +# riGetGridDimensions.cpp +# riGetCoarseningInfo.cpp +# riGetCellCenters.cpp +# riGetActiveCellCenters.cpp +# riGetCellCorners.cpp +# riGetActiveCellCorners.cpp riGetGridProperty.cpp riSetGridProperty.cpp - riGetPropertyNames.cpp - riGetWellNames.cpp - riGetWellStatus.cpp - riGetWellCells.cpp +# riGetPropertyNames.cpp +# riGetWellNames.cpp +# riGetWellStatus.cpp +# riGetWellCells.cpp ) if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") diff --git a/OctavePlugin/riGetActiveCellProperty.cpp b/OctavePlugin/riGetActiveCellProperty.cpp index 81b966f7d0..573e324f12 100644 --- a/OctavePlugin/riGetActiveCellProperty.cpp +++ b/OctavePlugin/riGetActiveCellProperty.cpp @@ -1,7 +1,12 @@ #include +#include + #include + #include "riSettings.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration + void getActiveCellProperty(Matrix& propertyFrames, const QString &serverName, quint16 serverPort, const qint64& caseId, QString propertyName, const int32NDArray& requestedTimeSteps, QString porosityModel) { @@ -63,44 +68,18 @@ void getActiveCellProperty(Matrix& propertyFrames, const QString &serverName, qu return; } - // Wait for available data for each timestep, then read data for each timestep + quint64 totalByteCount = byteCount * timestepCount; - for (size_t tIdx = 0; tIdx < timestepCount; ++tIdx) + double* internalMatrixData = propertyFrames.fortran_vec(); + QStringList errorMessages; + if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), totalByteCount, errorMessages)) { - while (socket.bytesAvailable() < (qint64)byteCount) - { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) - { - error((("Waiting for timestep data number: ") + QString::number(tIdx)+ ": " + socket.errorString()).toLatin1().data()); - octave_stdout << "Active cells: " << activeCellCount << ", Timesteps: " << timestepCount << std::endl; - return ; - } - OCTAVE_QUIT; - } - - qint64 bytesRead = 0; - double * internalMatrixData = propertyFrames.fortran_vec(); - -#if 0 - // Raw data transfer. Faster. Not possible when dealing with coarsening - // bytesRead = socket.read((char*)(internalMatrixData + tIdx * activeCellCount), byteCount); -#else - // Compatible transfer. Now the only one working - for (size_t cIdx = 0; cIdx < activeCellCount; ++cIdx) - { - socketStream >> internalMatrixData[tIdx * activeCellCount + cIdx]; - - if (socketStream.status() == QDataStream::Ok) bytesRead += sizeof(double); - } -#endif - - if ((qint64)byteCount != bytesRead) + for (int i = 0; i < errorMessages.size(); i++) { - error("Could not read binary double data properly from socket"); - octave_stdout << "Active cells: " << activeCellCount << ", Timesteps: " << timestepCount << std::endl; + error(errorMessages[i].toLatin1().data()); } - OCTAVE_QUIT; + return; } QString tmp = QString("riGetActiveCellProperty : Read %1").arg(propertyName); diff --git a/OctavePlugin/riGetGridProperty.cpp b/OctavePlugin/riGetGridProperty.cpp index e477cd767a..075c36ee48 100644 --- a/OctavePlugin/riGetGridProperty.cpp +++ b/OctavePlugin/riGetGridProperty.cpp @@ -4,7 +4,7 @@ #include #include "riSettings.h" -#include "riSocketTools.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 serverPort, @@ -83,14 +83,14 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 double* internalMatrixData = propertyFrames.fortran_vec(); QStringList errorMessages; - if (!readBlockData(socket, (char*)(internalMatrixData), totalByteCount, errorMessages)) + if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), totalByteCount, errorMessages)) { for (int i = 0; i < errorMessages.size(); i++) { error(errorMessages[i].toLatin1().data()); } - OCTAVE_QUIT; + return; } QString tmp = QString("riGetGridProperty : Read %1").arg(propertyName); diff --git a/OctavePlugin/riSetActiveCellProperty.cpp b/OctavePlugin/riSetActiveCellProperty.cpp index 4953f25778..b4981a70cc 100644 --- a/OctavePlugin/riSetActiveCellProperty.cpp +++ b/OctavePlugin/riSetActiveCellProperty.cpp @@ -1,6 +1,10 @@ #include +#include + #include + #include "riSettings.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration void setEclipseProperty(const Matrix& propertyFrames, const QString &hostName, quint16 port, @@ -47,27 +51,29 @@ void setEclipseProperty(const Matrix& propertyFrames, const QString &hostName, q socketStream << (qint64)timeStepByteCount; const double* internalData = propertyFrames.fortran_vec(); - qint64 dataWritten = socket.write((const char *)internalData, timeStepByteCount*timeStepCount); - if (dataWritten == timeStepByteCount*timeStepCount) + QStringList errorMessages; + if (!RiaSocketDataTransfer::writeBlockDataToSocket(&socket, (const char *)internalData, timeStepByteCount*timeStepCount, errorMessages)) { - QString tmp = QString("riSetActiveCellProperty : Wrote %1").arg(propertyName); - - if (caseId == -1) + for (int i = 0; i < errorMessages.size(); i++) { - tmp += QString(" to current case."); + octave_stdout << errorMessages[i].toStdString(); } - else - { - tmp += QString(" to case with Id = %1.").arg(caseId); - } - octave_stdout << tmp.toStdString() << " Active Cells : " << cellCount << " Time steps : " << timeStepCount << std::endl; + + return; + } + + QString tmp = QString("riSetActiveCellProperty : Wrote %1").arg(propertyName); + + if (caseId == -1) + { + tmp += QString(" to current case."); } else { - error("riSetActiveCellProperty : Was not able to write the proper amount of data to ResInsight:"); - octave_stdout << " Active Cells : " << cellCount << "Time steps : " << timeStepCount << " Data Written: " << dataWritten << " Should have written: " << timeStepCount * cellCount * sizeof(double) << std::endl; + tmp += QString(" to case with Id = %1.").arg(caseId); } + octave_stdout << tmp.toStdString() << " Active Cells : " << cellCount << " Time steps : " << timeStepCount << std::endl; while(socket.bytesToWrite() && socket.state() == QAbstractSocket::ConnectedState) { diff --git a/OctavePlugin/riSetGridProperty.cpp b/OctavePlugin/riSetGridProperty.cpp index f5afe0a0f7..8598d4b32e 100644 --- a/OctavePlugin/riSetGridProperty.cpp +++ b/OctavePlugin/riSetGridProperty.cpp @@ -1,6 +1,10 @@ #include +#include + #include + #include "riSettings.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration void setEclipseProperty(const NDArray& propertyFrames, const QString &hostName, quint16 port, @@ -64,41 +68,41 @@ void setEclipseProperty(const NDArray& propertyFrames, const QString &hostName, socketStream << (qint64)singleTimeStepByteCount; const double* internalData = propertyFrames.fortran_vec(); - qint64 dataWritten = 0; - - for (size_t tsIdx = 0; tsIdx < timeStepCount; ++tsIdx) - { - dataWritten += socket.write(((const char *)internalData) + tsIdx*singleTimeStepByteCount, singleTimeStepByteCount); - } - - if (dataWritten == singleTimeStepByteCount*timeStepCount) - { - QString tmp = QString("riSetGridProperty : Wrote %1").arg(propertyName); - if (caseId == -1) - { - tmp += QString(" to current case,"); - } - else + QStringList errorMessages; + if (!RiaSocketDataTransfer::writeBlockDataToSocket(&socket, (const char *)internalData, timeStepCount*singleTimeStepByteCount, errorMessages)) + { + for (int i = 0; i < errorMessages.size(); i++) { - tmp += QString(" to case with Id = %1,").arg(caseId); + octave_stdout << errorMessages[i].toStdString(); } - - tmp += QString(" grid index: %1, ").arg(gridIndex); - octave_stdout << tmp.toStdString() << " Time steps : " << timeStepCount << std::endl; + size_t cellCount = cellCountI * cellCountJ * cellCountK; + error("riSetGridProperty : Was not able to write the proper amount of data to ResInsight:"); + octave_stdout << " Cell count : " << cellCount << "Time steps : " << timeStepCount << std::endl; + + return; + } + + QString tmp = QString("riSetGridProperty : Wrote %1").arg(propertyName); + + if (caseId == -1) + { + tmp += QString(" to current case,"); } else { - size_t cellCount = cellCountI * cellCountJ * cellCountK; - error("riSetGridProperty : Was not able to write the proper amount of data to ResInsight:"); - octave_stdout << " Cell count : " << cellCount << "Time steps : " << timeStepCount << " Data Written: " << dataWritten << " Should have written: " << timeStepCount * cellCount * sizeof(double) << std::endl; + tmp += QString(" to case with Id = %1,").arg(caseId); } + + tmp += QString(" grid index: %1, ").arg(gridIndex); + + octave_stdout << tmp.toStdString() << " Time steps : " << timeStepCount << std::endl; while(socket.bytesToWrite() && socket.state() == QAbstractSocket::ConnectedState) { - octave_stdout << "Bytes to write: " << socket.bytesToWrite() << std::endl << std::flush; - socket.waitForBytesWritten(2000); +// octave_stdout << "Bytes to write: " << socket.bytesToWrite() << std::endl << std::flush; + socket.waitForBytesWritten(riOctavePlugin::longTimeOutMilliSecs); OCTAVE_QUIT; } diff --git a/OctavePlugin/riSocketTools.h b/OctavePlugin/riSocketTools.h index 63cc24d890..f142313c4f 100644 --- a/OctavePlugin/riSocketTools.h +++ b/OctavePlugin/riSocketTools.h @@ -2,7 +2,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages) +bool readBlockData_to_be_deleted(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages) { quint64 bytesRead = 0; int blockCount = 0; @@ -51,7 +51,7 @@ bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringL //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool writeBlockData(QTcpSocket& socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages) +bool writeBlockData_to_be_deleted(QTcpSocket& socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages) { quint64 bytesWritten = 0; int blockCount = 0; From 476387fda42f8916dda0c2bba226da825b90805a Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 15 Apr 2014 14:03:41 +0200 Subject: [PATCH 054/130] Block transfer for active cell info --- .../SocketInterface/RiaCaseInfoCommands.cpp | 15 ++------------- OctavePlugin/riGetActiveCellInfo.cpp | 6 ++---- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp index e6444f314d..2426f95252 100644 --- a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp @@ -132,20 +132,9 @@ class RiaGetActiveCellInfo: public RiaSocketCommand quint64 timestepByteCount = (quint64)(timestepResultCount*sizeof(qint32)); socketStream << timestepByteCount; - // Then write the data. - for (size_t tIdx = 0; tIdx < columnCount; ++tIdx) - { -#if 1 // Write data as raw bytes, fast but does not handle byteswapping - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)activeCellInfo[tIdx].data(), timestepByteCount); - -#else // Write data using QDataStream, does byteswapping for us. Must use QDataStream on client as well - for (size_t cIdx = 0; cIdx < activeCellInfo[tIdx].size(); ++cIdx) - { - socketStream << activeCellInfo[tIdx][cIdx]; - } -#endif - } + // Write data as raw bytes, fast but does not handle byteswapping + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)activeCellInfo.data(), columnCount*timestepByteCount); return true; } diff --git a/OctavePlugin/riGetActiveCellInfo.cpp b/OctavePlugin/riGetActiveCellInfo.cpp index a7213a3697..8a9f4bc8eb 100644 --- a/OctavePlugin/riGetActiveCellInfo.cpp +++ b/OctavePlugin/riGetActiveCellInfo.cpp @@ -2,10 +2,8 @@ #include #include - #include "riSettings.h" -#include "riSocketTools.h" - +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration void getActiveCellInfo(int32NDArray& activeCellInfo, const QString &hostName, quint16 port, const qint64& caseId, const QString& porosityModel) { @@ -67,7 +65,7 @@ void getActiveCellInfo(int32NDArray& activeCellInfo, const QString &hostName, qu qint32* internalMatrixData = (qint32*)activeCellInfo.fortran_vec()->mex_get_data(); QStringList errorMessages; - if (!readBlockData(socket, (char*)(internalMatrixData), columnCount * byteCountForOneTimestep, errorMessages)) + if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), columnCount * byteCountForOneTimestep, errorMessages)) { for (int i = 0; i < errorMessages.size(); i++) { From c0f5d0090f5724d5296543abf2fc2fc72eb3b9c6 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 15 Apr 2014 14:16:35 +0200 Subject: [PATCH 055/130] Removed riSocketTools and updated use of block data transfer --- OctavePlugin/CMakeLists.txt | 45 +++++++------- OctavePlugin/riGetActiveCellCenters.cpp | 5 +- OctavePlugin/riGetActiveCellCorners.cpp | 4 +- OctavePlugin/riGetCellCenters.cpp | 5 +- OctavePlugin/riGetCellCorners.cpp | 4 +- OctavePlugin/riGetCurrentCase.cpp | 1 - OctavePlugin/riSocketTools.h | 80 ------------------------- 7 files changed, 31 insertions(+), 113 deletions(-) delete mode 100644 OctavePlugin/riSocketTools.h diff --git a/OctavePlugin/CMakeLists.txt b/OctavePlugin/CMakeLists.txt index a49a9e21d0..4ee4dcc138 100644 --- a/OctavePlugin/CMakeLists.txt +++ b/OctavePlugin/CMakeLists.txt @@ -4,28 +4,28 @@ # See http://www.cmake.org/Wiki/CMakeUserFindOctave set(CPP_SOURCES - riGetActiveCellProperty.cpp - riSetActiveCellProperty.cpp -# riGetActiveCellInfo.cpp -# riGetMainGridDimensions.cpp -# riGetCurrentCase.cpp -# riGetCaseGroups.cpp -# riGetSelectedCases.cpp -# riGetCases.cpp -# riGetTimeStepDates.cpp -# riGetTimeStepDays.cpp -# riGetGridDimensions.cpp -# riGetCoarseningInfo.cpp -# riGetCellCenters.cpp -# riGetActiveCellCenters.cpp -# riGetCellCorners.cpp -# riGetActiveCellCorners.cpp - riGetGridProperty.cpp - riSetGridProperty.cpp -# riGetPropertyNames.cpp -# riGetWellNames.cpp -# riGetWellStatus.cpp -# riGetWellCells.cpp + riGetActiveCellProperty.cpp + riSetActiveCellProperty.cpp + riGetActiveCellInfo.cpp + riGetMainGridDimensions.cpp + riGetCurrentCase.cpp + riGetCaseGroups.cpp + riGetSelectedCases.cpp + riGetCases.cpp + riGetTimeStepDates.cpp + riGetTimeStepDays.cpp + riGetGridDimensions.cpp + riGetCoarseningInfo.cpp + riGetCellCenters.cpp + riGetActiveCellCenters.cpp + riGetCellCorners.cpp + riGetActiveCellCorners.cpp + riGetGridProperty.cpp + riSetGridProperty.cpp + riGetPropertyNames.cpp + riGetWellNames.cpp + riGetWellStatus.cpp + riGetWellCells.cpp ) if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") @@ -143,7 +143,6 @@ if (RESINSIGHT_OCTAVE_PLUGIN_QMAKE AND RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE) "${CMAKE_CURRENT_BINARY_DIR}/riGetWellCells.oct" SOURCES ${CPP_SOURCES} - riSocketTools.h riSettings.h ) diff --git a/OctavePlugin/riGetActiveCellCenters.cpp b/OctavePlugin/riGetActiveCellCenters.cpp index a98ba06bac..862172ba0a 100644 --- a/OctavePlugin/riGetActiveCellCenters.cpp +++ b/OctavePlugin/riGetActiveCellCenters.cpp @@ -4,7 +4,7 @@ #include #include "riSettings.h" -#include "riSocketTools.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration void getActiveCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 port, const qint32& caseId, const QString& porosityModel) @@ -66,7 +66,8 @@ void getActiveCellCenters(NDArray& cellCenterValues, const QString &hostName, qu double* internalMatrixData = cellCenterValues.fortran_vec(); QStringList errorMessages; - if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) + + if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), byteCount, errorMessages)) { for (int i = 0; i < errorMessages.size(); i++) { diff --git a/OctavePlugin/riGetActiveCellCorners.cpp b/OctavePlugin/riGetActiveCellCorners.cpp index 47ffad52bc..d018310285 100644 --- a/OctavePlugin/riGetActiveCellCorners.cpp +++ b/OctavePlugin/riGetActiveCellCorners.cpp @@ -4,7 +4,7 @@ #include #include "riSettings.h" -#include "riSocketTools.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration void getActiveCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 port, const qint32& caseId, const QString& porosityModel) @@ -66,7 +66,7 @@ void getActiveCellCorners(NDArray& cellCornerValues, const QString &hostName, qu double* internalMatrixData = cellCornerValues.fortran_vec(); QStringList errorMessages; - if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) + if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), byteCount, errorMessages)) { for (int i = 0; i < errorMessages.size(); i++) { diff --git a/OctavePlugin/riGetCellCenters.cpp b/OctavePlugin/riGetCellCenters.cpp index 4f57d08a2b..a8255b6fb5 100644 --- a/OctavePlugin/riGetCellCenters.cpp +++ b/OctavePlugin/riGetCellCenters.cpp @@ -4,7 +4,7 @@ #include #include "riSettings.h" -#include "riSocketTools.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration void getCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 port, const qint32& caseId, const quint32& gridIndex) @@ -69,10 +69,9 @@ void getCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 dv(3) = 3; cellCenterValues.resize(dv); - double* internalMatrixData = cellCenterValues.fortran_vec(); QStringList errorMessages; - if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) + if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), byteCount, errorMessages)) { for (int i = 0; i < errorMessages.size(); i++) { diff --git a/OctavePlugin/riGetCellCorners.cpp b/OctavePlugin/riGetCellCorners.cpp index 2571371a76..2ed5d264b9 100644 --- a/OctavePlugin/riGetCellCorners.cpp +++ b/OctavePlugin/riGetCellCorners.cpp @@ -4,7 +4,7 @@ #include #include "riSettings.h" -#include "riSocketTools.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration @@ -74,7 +74,7 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 double* internalMatrixData = cellCornerValues.fortran_vec(); QStringList errorMessages; - if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) + if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), byteCount, errorMessages)) { for (int i = 0; i < errorMessages.size(); i++) { diff --git a/OctavePlugin/riGetCurrentCase.cpp b/OctavePlugin/riGetCurrentCase.cpp index 88cc38088d..80b0ffe4ac 100644 --- a/OctavePlugin/riGetCurrentCase.cpp +++ b/OctavePlugin/riGetCurrentCase.cpp @@ -3,7 +3,6 @@ #include #include "riSettings.h" -#include "riSocketTools.h" void getCurrentCase(qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId, const QString &hostName, quint16 port) { diff --git a/OctavePlugin/riSocketTools.h b/OctavePlugin/riSocketTools.h deleted file mode 100644 index f142313c4f..0000000000 --- a/OctavePlugin/riSocketTools.h +++ /dev/null @@ -1,80 +0,0 @@ - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool readBlockData_to_be_deleted(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages) -{ - quint64 bytesRead = 0; - int blockCount = 0; - - quint64 maxBlockSize = riOctavePlugin::socketMaxByteCount; - - while (bytesRead < bytesToRead) - { - if (socket.bytesAvailable()) - { - quint64 byteCountToRead = qMin(bytesToRead - bytesRead, maxBlockSize); - - qint64 actuallyBytesRead = socket.read(data + bytesRead, byteCountToRead); - if (actuallyBytesRead < 0) - { - errorMessages.push_back("Error detected when reading data, error string from socket :"); - errorMessages.push_back(socket.errorString()); - - return false; - } - - bytesRead += actuallyBytesRead; - - octave_stdout << "Bytes read " << bytesRead << " of total " << bytesToRead << std::endl; - - blockCount++; - } - else - { - if (!socket.waitForReadyRead()) - { - errorMessages.push_back("Waited for data for %1 milli seconds."); - errorMessages.push_back(socket.errorString()); - - return false; - } - } - } - - octave_stdout << "Bytes read " << bytesToRead << std::endl; - - return true; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool writeBlockData_to_be_deleted(QTcpSocket& socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages) -{ - quint64 bytesWritten = 0; - int blockCount = 0; - - quint64 maxBlockSize = riOctavePlugin::socketMaxByteCount; - - while (bytesWritten < bytesToWrite) - { - quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize); - - qint64 actuallyBytesWritten = socket.write(data + bytesWritten, byteCountToWrite); - if (actuallyBytesWritten < 0) - { - errorMessages.push_back("Error detected when writing data, error string from socket"); - errorMessages.push_back(socket.errorString()); - - return false; - } - - bytesWritten += actuallyBytesWritten; - - blockCount++; - } - - return true; -} From 8eb040e7cb0ec9b834fe5cbeab84bd87946db2a3 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 15 Apr 2014 16:20:21 +0200 Subject: [PATCH 056/130] Fixed block transfer --- ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp index 2426f95252..e81b9db3ea 100644 --- a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp @@ -132,9 +132,10 @@ class RiaGetActiveCellInfo: public RiaSocketCommand quint64 timestepByteCount = (quint64)(timestepResultCount*sizeof(qint32)); socketStream << timestepByteCount; - - // Write data as raw bytes, fast but does not handle byteswapping - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)activeCellInfo.data(), columnCount*timestepByteCount); + for (size_t tIdx = 0; tIdx < columnCount; ++tIdx) + { + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)activeCellInfo[tIdx].data(), timestepByteCount); + } return true; } From d10177494e06d966cf84d1a98d7213190bfc6070 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 4 Apr 2014 10:59:21 +0200 Subject: [PATCH 057/130] Added ternary saturation visualization Ternary saturation available on top of dynamic results Created visualization for ternary based on SOIL, SGAS and SWAT --- .../ModelVisualization/RivGridPartMgr.cpp | 126 ++++++++++++++++-- .../ModelVisualization/RivGridPartMgr.h | 7 + ApplicationCode/ProjectDataModel/RimDefines.h | 1 + .../ProjectDataModel/RimReservoirView.cpp | 2 +- .../ProjectDataModel/RimResultDefinition.cpp | 21 ++- .../ProjectDataModel/RimResultDefinition.h | 2 + 6 files changed, 145 insertions(+), 14 deletions(-) diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index 7da5466ff8..7258c11d0a 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -41,6 +41,8 @@ #include "Rim3dOverlayInfoConfig.h" #include "RimReservoirCellResultsCacher.h" #include "RivSourceInfo.h" +#include "cvfRenderState_FF.h" +#include "cafProgressInfo.h" @@ -250,15 +252,23 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* { CVF_ASSERT(cellResultSlot); - const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper(); RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); - + cvf::ref surfaceFacesColorArray; + // Outer surface if (m_surfaceFaces.notNull()) { - if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) + if (cellResultSlot->isTernarySaturationSelected()) + { + surfaceFacesColorArray = new cvf::Color3ubArray; + + const std::vector& quadsToGridCells = m_surfaceGenerator.quadToGridCellIndices(); + + RivTransmissibilityColorMapper::updateTernarySaturationColorArray(timeStepIndex, cellResultSlot, m_grid.p(), surfaceFacesColorArray.p(), quadsToGridCells); + } + else if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) { const std::vector& quadsToFaceTypes = m_surfaceGenerator.quadToFace(); const std::vector& quadsToGridCells = m_surfaceGenerator.quadToGridCellIndices(); @@ -309,16 +319,41 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* } cvf::DrawableGeo* dg = dynamic_cast(m_surfaceFaces->drawable()); - if (dg) dg->setTextureCoordArray(m_surfaceFacesTextureCoords.p()); + if (surfaceFacesColorArray.notNull()) + { + if (dg) + { + dg->setColorArray(surfaceFacesColorArray.p()); + } - caf::PolygonOffset polygonOffset = caf::PO_1; - caf::ScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); + cvf::ref colorArrayEffect = new cvf::Effect; - scalarEffgen.setOpacityLevel(m_opacityLevel); + cvf::ref mat = new cvf::RenderStateMaterial_FF(cvf::Color3::BLUE); + mat->enableColorMaterial(true); + colorArrayEffect->setRenderState(mat.p()); - cvf::ref scalarEffect = scalarEffgen.generateEffect(); + cvf::ref lighting = new cvf::RenderStateLighting_FF; + lighting->enableTwoSided(true); + colorArrayEffect->setRenderState(lighting.p()); + + m_surfaceFaces->setEffect(colorArrayEffect.p()); + } + else + { + if (dg) + { + dg->setTextureCoordArray(m_surfaceFacesTextureCoords.p()); + } - m_surfaceFaces->setEffect(scalarEffect.p()); + caf::PolygonOffset polygonOffset = caf::PO_1; + caf::ScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); + + scalarEffgen.setOpacityLevel(m_opacityLevel); + + cvf::ref scalarEffect = scalarEffgen.generateEffect(); + + m_surfaceFaces->setEffect(scalarEffect.p()); + } } // Faults @@ -535,3 +570,76 @@ void RivTransmissibilityColorMapper::updateCombinedTransmissibilityTextureCoordi } } + + +//-------------------------------------------------------------------------------------------------- +/// Helper class used to provide zero for all cells +/// This way we can avoid to test if a StructGridScalarDataAccess object is valid before reading out the value. +//-------------------------------------------------------------------------------------------------- +class ScalarDataAccessZeroForAllCells : public cvf::StructGridScalarDataAccess +{ +public: + virtual double cellScalar(size_t cellIndex) const + { + return 0.0; + } + virtual void setCellScalar(size_t cellIndex, double value) + { + } +}; + + +//-------------------------------------------------------------------------------------------------- +/// Creates and assigns a ternary saturation color for all four vertices of a quad representing a cell face +/// +/// Loads ternary saturation results SOIL, SWAT and SGAS +/// If any of these are not present, the values for a missing component is set to 0.0 +//-------------------------------------------------------------------------------------------------- +void RivTransmissibilityColorMapper::updateTernarySaturationColorArray(size_t timeStepIndex, RimResultSlot* cellResultSlot, const RigGridBase* grid, cvf::Color3ubArray* colorArray, const std::vector& quadsToGridCells) +{ + RimReservoirCellResultsStorage* gridCellResults = cellResultSlot->currentGridCellResults(); + if (!gridCellResults) return; + + RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); + if (!eclipseCase) return; + + size_t soilScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); + size_t sgasScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); + size_t swatScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); + + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); + + cvf::ref dataAccessObjectSoil = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, soilScalarSetIndex); + if (dataAccessObjectSoil.isNull()) dataAccessObjectSoil = new ScalarDataAccessZeroForAllCells; + + cvf::ref dataAccessObjectSgas = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, sgasScalarSetIndex); + if (dataAccessObjectSgas.isNull()) dataAccessObjectSgas = new ScalarDataAccessZeroForAllCells; + + cvf::ref dataAccessObjectSwat = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, swatScalarSetIndex); + if (dataAccessObjectSwat.isNull()) dataAccessObjectSwat = new ScalarDataAccessZeroForAllCells; + + size_t numVertices = quadsToGridCells.size()*4; + + colorArray->resize(numVertices); + + cvf::Color3f ternaryColor; + cvf::Color3ub ternaryColorByte; + +#pragma omp parallel for private(ternaryColor, ternaryColorByte) + for (int idx = 0; idx < static_cast(quadsToGridCells.size()); idx++) + { + size_t gridCellIndex = quadsToGridCells[idx]; + + ternaryColor.r() = dataAccessObjectSgas->cellScalar(gridCellIndex); + ternaryColor.g() = dataAccessObjectSoil->cellScalar(gridCellIndex); + ternaryColor.b() = dataAccessObjectSwat->cellScalar(gridCellIndex); + + ternaryColorByte.set(ternaryColor.rByte(), ternaryColor.gByte(), ternaryColor.bByte()); + + size_t j; + for (j = 0; j < 4; j++) + { + colorArray->set(idx*4 + j, ternaryColorByte); + } + } +} diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.h b/ApplicationCode/ModelVisualization/RivGridPartMgr.h index b194f451a1..7658a77353 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.h @@ -50,6 +50,13 @@ class RivTransmissibilityColorMapper cvf::Vec2fArray* textureCoords, const std::vector& quadsToFaceTypes, const std::vector& quadsToGridCells); + + static void updateTernarySaturationColorArray( + size_t timeStepIndex, + RimResultSlot* cellResultSlot, + const RigGridBase* grid, + cvf::Color3ubArray* colorArray, + const std::vector& quadsToGridCells); }; diff --git a/ApplicationCode/ProjectDataModel/RimDefines.h b/ApplicationCode/ProjectDataModel/RimDefines.h index 95313686a3..2dbe096fbc 100644 --- a/ApplicationCode/ProjectDataModel/RimDefines.h +++ b/ApplicationCode/ProjectDataModel/RimDefines.h @@ -43,5 +43,6 @@ class RimDefines static QString undefinedGridFaultName() { return "Undefined grid faults"; } static QString combinedTransmissibilityResultName() { return "TRANSXYZ"; } + static QString ternarySaturationResultName() { return "TERNARY"; } }; diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp index 7c9e6587d4..84a1af1275 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp @@ -818,7 +818,7 @@ void RimReservoirView::updateCurrentTimeStep() { m_reservoirGridPartManager->updateCellEdgeResultColor(geometriesToRecolor[i], m_currentTimeStep, this->cellResult(), this->cellEdgeResult()); } - else if (this->animationMode() && this->cellResult()->hasResult()) + else if ((this->animationMode() && this->cellResult()->hasResult()) || this->cellResult()->isTernarySaturationSelected()) { m_reservoirGridPartManager->updateCellResultColor(geometriesToRecolor[i], m_currentTimeStep, this->cellResult()); } diff --git a/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp index ed298330b8..7a039c0ae8 100644 --- a/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp @@ -160,10 +160,10 @@ QList RimResultDefinition::calculateValueOptions(const c QStringList varList = getResultVariableListForCurrentUIFieldSettings(); bool hasCombinedTransmissibility = false; + QList optionList; for (int i = 0; i < varList.size(); ++i) { - if (varList[i].compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) { hasCombinedTransmissibility = true; @@ -171,7 +171,6 @@ QList RimResultDefinition::calculateValueOptions(const c } optionList.push_back(caf::PdmOptionItemInfo(varList[i], varList[i])); - } if (hasCombinedTransmissibility) @@ -179,6 +178,11 @@ QList RimResultDefinition::calculateValueOptions(const c optionList.push_front(caf::PdmOptionItemInfo(RimDefines::combinedTransmissibilityResultName(), RimDefines::combinedTransmissibilityResultName())); } + if (m_resultTypeUiField == RimDefines::DYNAMIC_NATIVE) + { + optionList.push_front(caf::PdmOptionItemInfo(RimDefines::ternarySaturationResultName(), RimDefines::ternarySaturationResultName())); + } + optionList.push_front(caf::PdmOptionItemInfo( RimDefines::undefinedResultName(), RimDefines::undefinedResultName() )); if (useOptionsOnly) *useOptionsOnly = true; @@ -223,7 +227,6 @@ void RimResultDefinition::loadResult() gridCellResults->findOrLoadScalarResult(m_resultType(), m_resultVariable); } } - } @@ -251,7 +254,6 @@ bool RimResultDefinition::hasStaticResult() const //-------------------------------------------------------------------------------------------------- bool RimResultDefinition::hasResult() const { - if (this->currentGridCellResults() && this->currentGridCellResults()->cellResults()) { const RigCaseCellResultsData* gridCellResults = this->currentGridCellResults()->cellResults(); @@ -341,3 +343,14 @@ void RimResultDefinition::setPorosityModelUiFieldHidden(bool hide) { m_porosityModelUiField.setUiHidden(true); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimResultDefinition::isTernarySaturationSelected() const +{ + bool isTernary = (m_resultType() == RimDefines::DYNAMIC_NATIVE) && + (m_resultVariable().compare(RimDefines::ternarySaturationResultName(), Qt::CaseInsensitive) == 0); + + return isTernary; +} diff --git a/ApplicationCode/ProjectDataModel/RimResultDefinition.h b/ApplicationCode/ProjectDataModel/RimResultDefinition.h index 2c7b6c28cf..dbe558eac2 100644 --- a/ApplicationCode/ProjectDataModel/RimResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimResultDefinition.h @@ -55,6 +55,8 @@ class RimResultDefinition : public caf::PdmObject bool hasStaticResult() const; bool hasDynamicResult() const; bool hasResult() const; + bool isTernarySaturationSelected() const; + RimReservoirCellResultsStorage* currentGridCellResults() const; From 79b523522d222165616f2282b55af4bde28ee1ef Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 4 Apr 2014 11:16:00 +0200 Subject: [PATCH 058/130] Show ternary info in result info by picking on cells --- .../Rim3dOverlayInfoConfig.cpp | 8 ++++- .../ProjectDataModel/RimReservoirView.cpp | 33 ++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp index f0d4ac756a..ada49281c4 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp @@ -140,6 +140,11 @@ void Rim3dOverlayInfoConfig::update3DInfo() "Cell count. Total: %2 Active: %3
" "Main Grid I,J,K: %4, %5, %6 Z-Scale: %7
").arg(caseName, totCellCount, activeCellCountText, iSize, jSize, kSize, zScale); + if (m_reservoirView->cellResult()->isTernarySaturationSelected()) + { + infoText += QString("Cell Property: %1 ").arg(propName); + } + if (m_reservoirView->animationMode() && m_reservoirView->cellResult()->hasResult()) { infoText += QString("Cell Property: %1 ").arg(propName); @@ -196,7 +201,8 @@ void Rim3dOverlayInfoConfig::update3DInfo() if ( m_reservoirView->cellResult()->hasDynamicResult() || m_reservoirView->propertyFilterCollection()->hasActiveDynamicFilters() - || m_reservoirView->wellCollection()->hasVisibleWellPipes()) + || m_reservoirView->wellCollection()->hasVisibleWellPipes() + || m_reservoirView->cellResult()->isTernarySaturationSelected()) { int currentTimeStep = m_reservoirView->currentTimeStep(); QDateTime date = m_reservoirView->currentGridCellResults()->cellResults()->timeStepDate(0, currentTimeStep); diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp index 84a1af1275..9b77ad9d8e 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp @@ -1107,7 +1107,38 @@ void RimReservoirView::appendCellResultInfo(size_t gridIndex, size_t cellIndex, RigCaseData* eclipseCase = m_reservoir->reservoirData(); RigGridBase* grid = eclipseCase->grid(gridIndex); - if (this->cellResult()->hasResult()) + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); + cvf::ref dataAccessObject; + + if (this->cellResult()->isTernarySaturationSelected()) + { + RimReservoirCellResultsStorage* gridCellResults = this->cellResult()->currentGridCellResults(); + if (gridCellResults) + { + size_t soilScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); + size_t sgasScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); + size_t swatScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); + + cvf::ref dataAccessObjectX = eclipseCase->dataAccessObject(grid, porosityModel, 0, soilScalarSetIndex); + cvf::ref dataAccessObjectY = eclipseCase->dataAccessObject(grid, porosityModel, 0, sgasScalarSetIndex); + cvf::ref dataAccessObjectZ = eclipseCase->dataAccessObject(grid, porosityModel, 0, swatScalarSetIndex); + + double scalarValue = 0.0; + + if (dataAccessObjectX.notNull()) scalarValue = dataAccessObjectX->cellScalar(cellIndex); + else scalarValue = 0.0; + resultInfoText->append(QString("SOIL : %1\n").arg(scalarValue)); + + if (dataAccessObjectY.notNull()) scalarValue = dataAccessObjectY->cellScalar(cellIndex); + else scalarValue = 0.0; + resultInfoText->append(QString("SGAS : %1\n").arg(scalarValue)); + + if (dataAccessObjectZ.notNull()) scalarValue = dataAccessObjectZ->cellScalar(cellIndex); + else scalarValue = 0.0; + resultInfoText->append(QString("SWAT : %1\n").arg(scalarValue)); + } + } + else if (this->cellResult()->hasResult()) { RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); cvf::ref dataAccessObject; From 7dda4d8437c049dc75b335f1367081265e630f84 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 4 Apr 2014 11:30:01 +0200 Subject: [PATCH 059/130] Remove ternary from property filter result selection list --- .../RimCellPropertyFilter.cpp | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp b/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp index ea89ebb599..abb2b6d3fc 100644 --- a/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp @@ -124,7 +124,26 @@ void RimCellPropertyFilter::fieldChangedByUi(const caf::PdmFieldHandle* changedF //-------------------------------------------------------------------------------------------------- QList RimCellPropertyFilter::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) { - return resultDefinition->calculateValueOptions(fieldNeedingOptions, useOptionsOnly); + QList optionItems = resultDefinition->calculateValueOptions(fieldNeedingOptions, useOptionsOnly); + + // Remove ternary from list, as it is not supported to perform filtering on a ternary result + int ternaryIndex = -1; + for (int i = 0; i < optionItems.size(); i++) + { + QString text = optionItems[i].optionUiText; + + if (text.compare(RimDefines::ternarySaturationResultName(), Qt::CaseInsensitive) == 0) + { + ternaryIndex = i; + } + } + + if (ternaryIndex != -1) + { + optionItems.takeAt(ternaryIndex); + } + + return optionItems; } //-------------------------------------------------------------------------------------------------- From 0e92bc5d3fdfcb2c7dbc45a0c693a0fff29657f9 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 7 Apr 2014 13:18:39 +0200 Subject: [PATCH 060/130] Added ternary saturation overlay item --- .../ModelVisualization/CMakeLists_files.cmake | 4 +- .../RivTernarySaturationOverlayItem.cpp | 200 ++++++++++++++++++ .../RivTernarySaturationOverlayItem.h | 62 ++++++ .../ProjectDataModel/RimReservoirView.cpp | 18 ++ .../ProjectDataModel/RimReservoirView.h | 3 + ApplicationCode/UserInterface/RiuViewer.cpp | 16 ++ ApplicationCode/UserInterface/RiuViewer.h | 5 + 7 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp create mode 100644 ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h diff --git a/ApplicationCode/ModelVisualization/CMakeLists_files.cmake b/ApplicationCode/ModelVisualization/CMakeLists_files.cmake index 6b03dc5a69..02509f21c9 100644 --- a/ApplicationCode/ModelVisualization/CMakeLists_files.cmake +++ b/ApplicationCode/ModelVisualization/CMakeLists_files.cmake @@ -11,6 +11,7 @@ ${CEE_CURRENT_LIST_DIR}RivFaultPartMgr.h ${CEE_CURRENT_LIST_DIR}RivFaultGeometryGenerator.h ${CEE_CURRENT_LIST_DIR}RivNNCGeometryGenerator.h ${CEE_CURRENT_LIST_DIR}RivGridPartMgr.h +${CEE_CURRENT_LIST_DIR}RivTernarySaturationOverlayItem.h ${CEE_CURRENT_LIST_DIR}RivReservoirPartMgr.h ${CEE_CURRENT_LIST_DIR}RivReservoirViewPartMgr.h ${CEE_CURRENT_LIST_DIR}RivPipeGeometryGenerator.h @@ -27,9 +28,10 @@ set (SOURCE_GROUP_SOURCE_FILES ${CEE_CURRENT_LIST_DIR}RivCellEdgeEffectGenerator.cpp ${CEE_CURRENT_LIST_DIR}RivColorTableArray.cpp ${CEE_CURRENT_LIST_DIR}RivFaultPartMgr.cpp -${CEE_CURRENT_LIST_DIR}RivFaultGeometryGenerator.cpp ${CEE_CURRENT_LIST_DIR}RivNNCGeometryGenerator.cpp +${CEE_CURRENT_LIST_DIR}RivFaultGeometryGenerator.cpp ${CEE_CURRENT_LIST_DIR}RivGridPartMgr.cpp +${CEE_CURRENT_LIST_DIR}RivTernarySaturationOverlayItem.cpp ${CEE_CURRENT_LIST_DIR}RivReservoirFaultsPartMgr.cpp ${CEE_CURRENT_LIST_DIR}RivReservoirPartMgr.cpp ${CEE_CURRENT_LIST_DIR}RivReservoirViewPartMgr.cpp diff --git a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp new file mode 100644 index 0000000000..565dbc21eb --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp @@ -0,0 +1,200 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA, Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#include "cvfBase.h" + +#include "RivTernarySaturationOverlayItem.h" + + +#include "cvfOpenGL.h" +#include "cvfViewport.h" +#include "cvfCamera.h" +#include "cvfTextDrawer.h" +#include "cvfFont.h" +#include "cvfMatrixState.h" + +#include "cvfRenderState_FF.h" +#include "cvfRenderStateDepth.h" +#include "cvfRenderStatePolygonOffset.h" + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivTernarySaturationOverlayItem::RivTernarySaturationOverlayItem(cvf::Font* font) + : m_textColor(cvf::Color3::BLACK), + m_font(font), + m_size(100, 120) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivTernarySaturationOverlayItem::~RivTernarySaturationOverlayItem() +{ + // Empty destructor to avoid errors with undefined types when cvf::ref's destructor gets called +} + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivTernarySaturationOverlayItem::setAxisLabelsColor(const cvf::Color3f& color) +{ + m_textColor = color; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec2ui RivTernarySaturationOverlayItem::sizeHint() +{ + return m_size; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivTernarySaturationOverlayItem::setSize(const cvf::Vec2ui& size) +{ + m_size = size; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivTernarySaturationOverlayItem::render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size) +{ + render(oglContext, position, size, false); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivTernarySaturationOverlayItem::renderSoftware(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size) +{ + render(oglContext, position, size, true); +} + + +//-------------------------------------------------------------------------------------------------- +/// Set up camera/viewport and render +//-------------------------------------------------------------------------------------------------- +void RivTernarySaturationOverlayItem::render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size, bool software) +{ + if (size.x() <= 0 || size.y() <= 0) + { + return; + } + + cvf::Camera camera; + camera.setViewport(position.x(), position.y(), size.x(), size.y()); + camera.setProjectionAsPixelExact2D(); + camera.setViewMatrix(cvf::Mat4d::IDENTITY); + camera.applyOpenGL(); + camera.viewport()->applyOpenGL(oglContext, cvf::Viewport::CLEAR_DEPTH); + + cvf::TextDrawer textDrawer(m_font.p()); + textDrawer.setTextColor(m_textColor); + + textDrawer.addText("SWAT", cvf::Vec2f(0.0, 0.0)); + textDrawer.addText("SOIL", cvf::Vec2f(static_cast(size.x() - 28), 0.0)); + textDrawer.addText("SGAS", cvf::Vec2f(static_cast( (size.x() / 2) - 17 ), static_cast(size.y() - 10))); + textDrawer.renderSoftware(oglContext, camera); + + renderAxisImmediateMode(oglContext); + + CVF_CHECK_OGL(oglContext); +} + + + +//-------------------------------------------------------------------------------------------------- +/// Draw the axis using immediate mode OpenGL +//-------------------------------------------------------------------------------------------------- +void RivTernarySaturationOverlayItem::renderAxisImmediateMode(cvf::OpenGLContext* oglContext) +{ +#ifdef CVF_OPENGL_ES + CVF_UNUSED(layout); + CVF_FAIL_MSG("Not supported on OpenGL ES"); +#else + + cvf::RenderStateDepth depth(false); + depth.applyOpenGL(oglContext); + + cvf::RenderStateLighting_FF lighting(false); + lighting.applyOpenGL(oglContext); + + cvf::Color3ub colA(cvf::Color3::BLUE); + cvf::Color3ub colB(cvf::Color3::GREEN); + cvf::Color3ub colC(cvf::Color3::RED); + + float lowerBoundY = 20; + float upperBoundY = static_cast(m_size.y() - 20); + + cvf::Vec3f a(0, lowerBoundY, 0); + cvf::Vec3f b(static_cast(m_size.x()), lowerBoundY, 0); + cvf::Vec3f c(static_cast(m_size.x() / 2), upperBoundY, 0); + + + // Draw filled rectangle elements + glBegin(GL_TRIANGLE_FAN); + + glColor3ubv(colA.ptr()); + glVertex3fv(a.ptr()); + + glColor3ubv(colB.ptr()); + glVertex3fv(b.ptr()); + + glColor3ubv(colC.ptr()); + glVertex3fv(c.ptr()); + glVertex3fv(c.ptr()); + glEnd(); + + + // Lines + cvf::Color3ub linesColor(cvf::Color3::WHITE); + glColor3ubv(linesColor.ptr()); + glBegin(GL_LINE_LOOP); + glVertex3fv(a.ptr()); + glVertex3fv(b.ptr()); + glVertex3fv(c.ptr()); + glEnd(); + + cvf::RenderStateDepth resetDepth; + resetDepth.applyOpenGL(oglContext); + + // Reset render states + cvf::RenderStateLighting_FF resetLighting; + resetLighting.applyOpenGL(oglContext); + + CVF_CHECK_OGL(oglContext); +#endif // CVF_OPENGL_ES + +} + + diff --git a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h new file mode 100644 index 0000000000..eb03b4d90a --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h @@ -0,0 +1,62 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA, Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfOverlayItem.h" +#include "cvfMatrix4.h" +#include "cvfColor3.h" +#include "cvfString.h" + +namespace cvf { + +class Font; + +} + +//================================================================================================== +// +// +// +//================================================================================================== +class RivTernarySaturationOverlayItem : public cvf::OverlayItem +{ +public: + RivTernarySaturationOverlayItem(cvf::Font* font); + ~RivTernarySaturationOverlayItem(); + + virtual cvf::Vec2ui sizeHint(); + + virtual void render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size); + virtual void renderSoftware(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size); + + void setSize(const cvf::Vec2ui& size); + + void setAxisLabelsColor(const cvf::Color3f& color); + +private: + void render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size, bool software); + void renderAxisImmediateMode(cvf::OpenGLContext* oglContext); + +private: + cvf::Color3f m_textColor; // Text color + cvf::ref m_font; + + cvf::Vec2ui m_size; // Pixel size of draw area +}; + diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp index 9b77ad9d8e..20810f3096 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp @@ -74,6 +74,7 @@ #include #include "cafCeetronPlusNavigation.h" #include "RimFaultCollection.h" +#include "RivTernarySaturationOverlayItem.h" namespace caf { @@ -1445,6 +1446,23 @@ void RimReservoirView::updateLegends() this->cellEdgeResult()->legendConfig->setClosestToZeroValues(0, 0, 0, 0); this->cellEdgeResult()->legendConfig->setAutomaticRanges(cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE); } + + if (m_ternarySaturationOverlayItem.notNull()) + { + viewer()->removeOverlayItem(m_ternarySaturationOverlayItem.p()); + } + + if (this->cellResult()->isTernarySaturationSelected()) + { + if (m_ternarySaturationOverlayItem.isNull()) + { + cvf::Font* standardFont = RiaApplication::instance()->standardFont(); + m_ternarySaturationOverlayItem = new RivTernarySaturationOverlayItem(standardFont); + m_ternarySaturationOverlayItem->setLayout(cvf::OverlayItem::VERTICAL, cvf::OverlayItem::BOTTOM_LEFT); + } + + viewer()->addOverlayItem(m_ternarySaturationOverlayItem.p()); + } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.h b/ApplicationCode/ProjectDataModel/RimReservoirView.h index 6860e6dab0..955eeada1b 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.h +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.h @@ -57,6 +57,7 @@ namespace cvf class Transform; class ScalarMapperUniformLevels; class ModelBasicList; + class OverlayItem; } enum PartRenderMaskEnum @@ -200,6 +201,8 @@ class RimReservoirView : public caf::PdmObject cvf::ref m_reservoirGridPartManager; cvf::ref m_pipesPartManager; + cvf::ref m_ternarySaturationOverlayItem; + // Overridden PDM methods: public: virtual caf::PdmFieldHandle* userDescriptionField() { return &name; } diff --git a/ApplicationCode/UserInterface/RiuViewer.cpp b/ApplicationCode/UserInterface/RiuViewer.cpp index b2af5cf05e..354cc30af3 100644 --- a/ApplicationCode/UserInterface/RiuViewer.cpp +++ b/ApplicationCode/UserInterface/RiuViewer.cpp @@ -742,3 +742,19 @@ void RiuViewer::mousePressEvent(QMouseEvent* event) m_lastMousePressPosition = event->pos(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewer::addOverlayItem(cvf::OverlayItem* overlayItem) +{ + m_renderingSequence->firstRendering()->addOverlayItem(overlayItem); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewer::removeOverlayItem(cvf::OverlayItem* overlayItem) +{ + m_renderingSequence->firstRendering()->removeOverlayItem(overlayItem); +} + diff --git a/ApplicationCode/UserInterface/RiuViewer.h b/ApplicationCode/UserInterface/RiuViewer.h index eb89a5cedd..7e881a1464 100644 --- a/ApplicationCode/UserInterface/RiuViewer.h +++ b/ApplicationCode/UserInterface/RiuViewer.h @@ -34,6 +34,7 @@ class QCDEStyle; namespace cvf { class Part; + class OverlayItem; } //================================================================================================== @@ -64,6 +65,10 @@ class RiuViewer : public caf::Viewer void setHistogramPercentiles(double pmin, double pmax, double mean); void showAnimationProgress(bool enable); + + void addOverlayItem(cvf::OverlayItem* overlayItem); + void removeOverlayItem(cvf::OverlayItem* overlayItem); + public slots: virtual void slotSetCurrentFrame(int frameIndex); From 02c4f8cff7647899d535a548a0c7bad6aa147639 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 8 Apr 2014 08:36:39 +0200 Subject: [PATCH 061/130] Use timestep when creating data access object --- ApplicationCode/ProjectDataModel/RimReservoirView.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp index 20810f3096..2973482bfa 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp @@ -1120,9 +1120,9 @@ void RimReservoirView::appendCellResultInfo(size_t gridIndex, size_t cellIndex, size_t sgasScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); size_t swatScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); - cvf::ref dataAccessObjectX = eclipseCase->dataAccessObject(grid, porosityModel, 0, soilScalarSetIndex); - cvf::ref dataAccessObjectY = eclipseCase->dataAccessObject(grid, porosityModel, 0, sgasScalarSetIndex); - cvf::ref dataAccessObjectZ = eclipseCase->dataAccessObject(grid, porosityModel, 0, swatScalarSetIndex); + cvf::ref dataAccessObjectX = eclipseCase->dataAccessObject(grid, porosityModel, m_currentTimeStep, soilScalarSetIndex); + cvf::ref dataAccessObjectY = eclipseCase->dataAccessObject(grid, porosityModel, m_currentTimeStep, sgasScalarSetIndex); + cvf::ref dataAccessObjectZ = eclipseCase->dataAccessObject(grid, porosityModel, m_currentTimeStep, swatScalarSetIndex); double scalarValue = 0.0; From b158c0da9de9c2b500099da1a26a045b8b03ca4e Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 8 Apr 2014 08:37:22 +0200 Subject: [PATCH 062/130] Use polygon offsett to avoid flickering with mesh lines --- .../ModelVisualization/RivGridPartMgr.cpp | 17 +++++++++++++++++ Fwk/AppFwk/CommonCode/cafEffectGenerator.cpp | 6 +++--- Fwk/AppFwk/CommonCode/cafEffectGenerator.h | 3 +++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index 7258c11d0a..e9af3414c4 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -43,6 +43,8 @@ #include "RivSourceInfo.h" #include "cvfRenderState_FF.h" #include "cafProgressInfo.h" +#include "cvfRenderStatePolygonOffset.h" +#include "cvfRenderStateBlending.h" @@ -329,6 +331,7 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* cvf::ref colorArrayEffect = new cvf::Effect; cvf::ref mat = new cvf::RenderStateMaterial_FF(cvf::Color3::BLUE); + mat->setAlpha(m_opacityLevel); mat->enableColorMaterial(true); colorArrayEffect->setRenderState(mat.p()); @@ -336,6 +339,20 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* lighting->enableTwoSided(true); colorArrayEffect->setRenderState(lighting.p()); + // Simple transparency + if (m_opacityLevel < 1.0f) + { + cvf::ref blender = new cvf::RenderStateBlending; + blender->configureTransparencyBlending(); + colorArrayEffect->setRenderState(blender.p()); + } + + caf::PolygonOffset polygonOffset = caf::PO_1; + cvf::ref polyOffset = caf::EffectGenerator::createAndConfigurePolygonOffsetRenderState(polygonOffset); + colorArrayEffect->setRenderState(polyOffset.p()); + + m_surfaceFaces->setPriority(100); + m_surfaceFaces->setEffect(colorArrayEffect.p()); } else diff --git a/Fwk/AppFwk/CommonCode/cafEffectGenerator.cpp b/Fwk/AppFwk/CommonCode/cafEffectGenerator.cpp index b495d5132d..e5049e0d8d 100644 --- a/Fwk/AppFwk/CommonCode/cafEffectGenerator.cpp +++ b/Fwk/AppFwk/CommonCode/cafEffectGenerator.cpp @@ -107,7 +107,7 @@ cvf::String CommonShaderSources::light_AmbientDiffuse() //-------------------------------------------------------------------------------------------------- /// Static helper to configure polygon offset render state from enum //-------------------------------------------------------------------------------------------------- -static cvf::ref CreateAngConfigurePolygonOffsetRenderState(PolygonOffset polygonOffset) +cvf::ref EffectGenerator::createAndConfigurePolygonOffsetRenderState(PolygonOffset polygonOffset) { cvf::ref rs = new cvf::RenderStatePolygonOffset; if (polygonOffset == PO_NONE) @@ -301,7 +301,7 @@ void SurfaceEffectGenerator::updateCommonEffect(cvf::Effect* effect) const { if (m_polygonOffset != PO_NONE) { - cvf::ref polyOffset = CreateAngConfigurePolygonOffsetRenderState(m_polygonOffset); + cvf::ref polyOffset = EffectGenerator::createAndConfigurePolygonOffsetRenderState(m_polygonOffset); effect->setRenderState(polyOffset.p()); } @@ -479,7 +479,7 @@ void ScalarMapperEffectGenerator::updateCommonEffect(cvf::Effect* effect) const if (m_polygonOffset != PO_NONE) { - cvf::ref polyOffset = CreateAngConfigurePolygonOffsetRenderState(m_polygonOffset); + cvf::ref polyOffset = EffectGenerator::createAndConfigurePolygonOffsetRenderState(m_polygonOffset); effect->setRenderState(polyOffset.p()); } diff --git a/Fwk/AppFwk/CommonCode/cafEffectGenerator.h b/Fwk/AppFwk/CommonCode/cafEffectGenerator.h index a33c08412a..9d79c9d5c4 100644 --- a/Fwk/AppFwk/CommonCode/cafEffectGenerator.h +++ b/Fwk/AppFwk/CommonCode/cafEffectGenerator.h @@ -44,6 +44,7 @@ #include "cvfTextureImage.h" #include "cvfCollection.h" #include "cvfString.h" +#include "cvfRenderStatePolygonOffset.h" namespace caf { @@ -96,6 +97,8 @@ class EffectGenerator static void clearEffectCache(); static void releaseUnreferencedEffects(); + static cvf::ref createAndConfigurePolygonOffsetRenderState(caf::PolygonOffset polygonOffset); + protected: // Interface that must be implemented in base classes From b958d01540a50b5ab1ab3bc9d8cd6e368b9a12ce Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 8 Apr 2014 11:52:40 +0200 Subject: [PATCH 063/130] Added missing test for ternary saturation result --- ApplicationCode/ProjectDataModel/RimReservoirView.cpp | 3 ++- ApplicationCode/UserInterface/RiuMainWindow.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp index 2973482bfa..58e81185a3 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp @@ -530,7 +530,8 @@ void RimReservoirView::createDisplayModel() if (this->cellResult()->hasDynamicResult() || this->propertyFilterCollection()->hasActiveDynamicFilters() - || this->wellCollection->hasVisibleWellPipes()) + || this->wellCollection->hasVisibleWellPipes() + || this->cellResult()->isTernarySaturationSelected()) { CVF_ASSERT(currentGridCellResults()); diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index 930a0c337c..7210665d7a 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -660,7 +660,8 @@ void RiuMainWindow::refreshAnimationActions() { if (app->activeReservoirView()->cellResult()->hasDynamicResult() || app->activeReservoirView()->propertyFilterCollection()->hasActiveDynamicFilters() - || app->activeReservoirView()->wellCollection()->hasVisibleWellPipes()) + || app->activeReservoirView()->wellCollection()->hasVisibleWellPipes() + || app->activeReservoirView()->cellResult()->isTernarySaturationSelected()) { std::vector timeStepDates = app->activeReservoirView()->currentGridCellResults()->cellResults()->timeStepDates(0); bool showHoursAndMinutes = false; From 03ab3d0a344988cc9995463958668a9bf83309d4 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 11 Apr 2014 13:08:05 +0200 Subject: [PATCH 064/130] Ternary: Use shader based per vertex coloring effect --- .../ModelVisualization/RivGridPartMgr.cpp | 78 +++++++++++++------ .../ModelVisualization/RivGridPartMgr.h | 7 +- 2 files changed, 58 insertions(+), 27 deletions(-) diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index e9af3414c4..306aa3ec2f 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -45,6 +45,11 @@ #include "cafProgressInfo.h" #include "cvfRenderStatePolygonOffset.h" #include "cvfRenderStateBlending.h" +#include "cvfShaderProgramGenerator.h" +#include "cvfShaderSourceRepository.h" +#include "cvfUniform.h" +#include "cvfShaderSourceProvider.h" +#include "cvfShaderProgram.h" @@ -328,32 +333,10 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* dg->setColorArray(surfaceFacesColorArray.p()); } - cvf::ref colorArrayEffect = new cvf::Effect; - - cvf::ref mat = new cvf::RenderStateMaterial_FF(cvf::Color3::BLUE); - mat->setAlpha(m_opacityLevel); - mat->enableColorMaterial(true); - colorArrayEffect->setRenderState(mat.p()); - - cvf::ref lighting = new cvf::RenderStateLighting_FF; - lighting->enableTwoSided(true); - colorArrayEffect->setRenderState(lighting.p()); - - // Simple transparency - if (m_opacityLevel < 1.0f) - { - cvf::ref blender = new cvf::RenderStateBlending; - blender->configureTransparencyBlending(); - colorArrayEffect->setRenderState(blender.p()); - } - - caf::PolygonOffset polygonOffset = caf::PO_1; - cvf::ref polyOffset = caf::EffectGenerator::createAndConfigurePolygonOffsetRenderState(polygonOffset); - colorArrayEffect->setRenderState(polyOffset.p()); + cvf::ref perVertexColorEffect = createPerVertexColoringEffect(); + m_surfaceFaces->setEffect(perVertexColorEffect.p()); m_surfaceFaces->setPriority(100); - - m_surfaceFaces->setEffect(colorArrayEffect.p()); } else { @@ -485,6 +468,53 @@ RivGridPartMgr::~RivGridPartMgr() #endif } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RivGridPartMgr::createPerVertexColoringEffect() +{ + cvf::ref colorArrayEffect = new cvf::Effect; + + if (RiaApplication::instance()->useShaders()) + { + cvf::ShaderProgramGenerator gen("PerVertexColor", cvf::ShaderSourceProvider::instance()); + gen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard); + gen.addFragmentCode(cvf::ShaderSourceRepository::src_VaryingColorGlobalAlpha); + gen.addFragmentCode(caf::CommonShaderSources::light_AmbientDiffuse()); + gen.addFragmentCode(cvf::ShaderSourceRepository::fs_Standard); + + cvf::ref m_shaderProg = gen.generate(); + m_shaderProg->setDefaultUniform(new cvf::UniformFloat("u_alpha", m_opacityLevel)); + + colorArrayEffect->setShaderProgram(m_shaderProg.p()); + } + else + { + cvf::ref mat = new cvf::RenderStateMaterial_FF(cvf::Color3::BLUE); + mat->setAlpha(m_opacityLevel); + mat->enableColorMaterial(true); + colorArrayEffect->setRenderState(mat.p()); + + cvf::ref lighting = new cvf::RenderStateLighting_FF; + lighting->enableTwoSided(true); + colorArrayEffect->setRenderState(lighting.p()); + } + + // Simple transparency + if (m_opacityLevel < 1.0f) + { + cvf::ref blender = new cvf::RenderStateBlending; + blender->configureTransparencyBlending(); + colorArrayEffect->setRenderState(blender.p()); + } + + caf::PolygonOffset polygonOffset = caf::PO_1; + cvf::ref polyOffset = caf::EffectGenerator::createAndConfigurePolygonOffsetRenderState(polygonOffset); + colorArrayEffect->setRenderState(polyOffset.p()); + + return colorArrayEffect; +} + //-------------------------------------------------------------------------------------------------- /// diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.h b/ApplicationCode/ModelVisualization/RivGridPartMgr.h index 7658a77353..a33d435fb8 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.h @@ -29,6 +29,7 @@ namespace cvf class ModelBasicList; class Transform; class Part; + class Effect; } class RimResultSlot; @@ -80,15 +81,15 @@ class RivGridPartMgr: public cvf::Object void updateCellColor(cvf::Color4f color); void updateCellResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot); + void updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot); void appendPartsToModel(cvf::ModelBasicList* model); private: - void generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder, bool faultGeometry); - - + void generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder, bool faultGeometry); + cvf::ref createPerVertexColoringEffect(); private: size_t m_gridIdx; From 489b25531f2ff7b07189565d5b5b9c56c28b2122 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 14 Apr 2014 08:04:09 +0200 Subject: [PATCH 065/130] Hide UI for ternary saturation legend config --- .../ProjectDataModel/RimLegendConfig.cpp | 79 ++++++++++++++++--- .../ProjectDataModel/RimLegendConfig.h | 3 + 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp index b71d66fd4b..8a53df3136 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp @@ -480,6 +480,18 @@ void RimLegendConfig::updateFieldVisibility() m_userDefinedMaxValue.setUiHidden(true); m_userDefinedMinValue.setUiHidden(true); } + + if (m_reservoirView && m_reservoirView->cellResult() && m_reservoirView->cellResult()->isTernarySaturationSelected()) + { + if (m_mappingMode == LINEAR_DISCRETE) + { + m_numLevels.setUiHidden(false); + } + else + { + m_numLevels.setUiHidden(true); + } + } } //-------------------------------------------------------------------------------------------------- @@ -635,16 +647,61 @@ void RimLegendConfig::setClosestToZeroValues(double globalPosClosestToZero, doub //-------------------------------------------------------------------------------------------------- void RimLegendConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { - caf::PdmUiOrdering * formatGr = uiOrdering.addNewGroup("Format"); - formatGr->add(&m_numLevels); - formatGr->add(&m_precision); - formatGr->add(&m_tickNumberFormat); - formatGr->add(&m_colorRangeMode); - - caf::PdmUiOrdering * mappingGr = uiOrdering.addNewGroup("Mapping"); - mappingGr->add(&m_mappingMode); - mappingGr->add(&m_rangeMode); - mappingGr->add(&m_userDefinedMaxValue); - mappingGr->add(&m_userDefinedMinValue); + if (m_reservoirView && m_reservoirView->cellResult() && m_reservoirView->cellResult()->isTernarySaturationSelected()) + { + //TODO: Add support for discrete legend +// caf::PdmUiOrdering * formatGr = uiOrdering.addNewGroup("Ternary format"); +// formatGr->add(&m_mappingMode); +// formatGr->add(&m_numLevels); + + uiOrdering.setForgetRemainingFields(true); + } + else + { + caf::PdmUiOrdering * formatGr = uiOrdering.addNewGroup("Format"); + formatGr->add(&m_numLevels); + formatGr->add(&m_precision); + formatGr->add(&m_tickNumberFormat); + formatGr->add(&m_colorRangeMode); + + caf::PdmUiOrdering * mappingGr = uiOrdering.addNewGroup("Mapping"); + mappingGr->add(&m_mappingMode); + mappingGr->add(&m_rangeMode); + mappingGr->add(&m_userDefinedMaxValue); + mappingGr->add(&m_userDefinedMinValue); + } +} + +//-------------------------------------------------------------------------------------------------- +/// Return the number of levels if mapping mode is LINEAR_DISCRETE, else -1 +//-------------------------------------------------------------------------------------------------- +int RimLegendConfig::linearDiscreteLevelCount() const +{ + if (m_mappingMode == LINEAR_DISCRETE) + { + return m_numLevels; + } + + return -1; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimLegendConfig::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) +{ + if (m_reservoirView && m_reservoirView->cellResult() && m_reservoirView->cellResult()->isTernarySaturationSelected()) + { + if (fieldNeedingOptions == &m_mappingMode) + { + QList optionList; + optionList.push_back(caf::PdmOptionItemInfo(MappingEnum(LINEAR_DISCRETE).uiText(), LINEAR_DISCRETE)); + optionList.push_back(caf::PdmOptionItemInfo(MappingEnum(LINEAR_CONTINUOUS).uiText(), LINEAR_CONTINUOUS)); + + return optionList; + } + } + + return QList(); } diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.h b/ApplicationCode/ProjectDataModel/RimLegendConfig.h index f031c1e66d..117eefcc7c 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.h +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.h @@ -94,6 +94,8 @@ class RimLegendConfig: public caf::PdmObject cvf::ScalarMapper* scalarMapper() { return m_currentScalarMapper.p(); } cvf::OverlayScalarMapperLegend* legend() { return m_legend.p(); } + int linearDiscreteLevelCount() const; + protected: virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); virtual void initAfterRead(); @@ -104,6 +106,7 @@ class RimLegendConfig: public caf::PdmObject cvf::ref interpolateColorArray(const cvf::Color3ubArray& colorArray, cvf::uint targetColorCount); double roundToNumSignificantDigits(double value, double precision); + virtual QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly ); private: From b7377e1873b5f43e40a27f4411ae373d4f59a233 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 14 Apr 2014 08:21:33 +0200 Subject: [PATCH 066/130] Adde linebreak if no statistics are present --- ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp index ada49281c4..8e49426dae 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp @@ -189,6 +189,10 @@ void Rim3dOverlayInfoConfig::update3DInfo() infoText += QString("Fault results: %1
").arg(faultMapping); } } + else + { + infoText += "
"; + } if (m_reservoirView->animationMode() && m_reservoirView->cellEdgeResult()->hasResult()) From 89fc4629c8bbe3b0c2bfcd1c7c61e3889ea1906b Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 11:55:34 +0100 Subject: [PATCH 067/130] Added default editor for quint64 --- Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp index 822d2c3185..5bfee7de4f 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp @@ -65,10 +65,11 @@ CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, QString); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, int); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, double); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, float); +CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, quint64); + CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); - CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); From 040dc12e1bf0a6aaf2b7f2f85278e57f23e9be2f Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 11:58:49 +0100 Subject: [PATCH 068/130] Added property dialog --- Fwk/AppFwk/cafUserInterface/CMakeLists.txt | 3 + .../cafPdmUiPropertyDialog.cpp | 92 +++++++++++++++++++ .../cafUserInterface/cafPdmUiPropertyDialog.h | 70 ++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.cpp create mode 100644 Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.h diff --git a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt index 69496b3ffe..59b3f8e273 100644 --- a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt +++ b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt @@ -24,6 +24,7 @@ set( QOBJECT_HEADERS cafPdmUiColorEditor.h cafPdmUiPropertyView.h + cafPdmUiPropertyDialog.h cafPdmUiTreeView.h cafPdmUiTreeViewModel.h cafPdmUiListView.h @@ -57,6 +58,8 @@ add_library( ${PROJECT_NAME} cafPdmUiListViewEditor.cpp cafPdmUiListViewEditor.h cafPdmUiListView.cpp + cafPdmUiPropertyDialog.cpp + cafPdmUiPropertyDialog.h cafPdmUiPropertyView.cpp cafPdmUiPropertyView.h cafPdmUiPushButtonEditor.cpp diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.cpp new file mode 100644 index 0000000000..277dc3153d --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.cpp @@ -0,0 +1,92 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmUiPropertyDialog.h" + +#include "cafPdmObject.h" +#include "cafPdmUiPropertyView.h" + +#include +#include + +#include + + + +namespace caf { + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiPropertyDialog::PdmUiPropertyDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle) + : QDialog(parent) +{ + assert(object); + + m_pdmObject = object; + m_windowTitle = windowTitle; + + setupUi(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiPropertyDialog::setupUi() +{ + setWindowTitle(m_windowTitle); + + m_pdmUiPropertyView = new caf::PdmUiPropertyView(this); + + QVBoxLayout* dialogLayout = new QVBoxLayout; + setLayout(dialogLayout); + + dialogLayout->addWidget(m_pdmUiPropertyView); + m_pdmUiPropertyView->showProperties(m_pdmObject); + + // Buttons + QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + dialogLayout->addWidget(buttonBox); + + this->resize(400, 200); +} + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.h new file mode 100644 index 0000000000..4c4ca7b797 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.h @@ -0,0 +1,70 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include + +namespace caf +{ + class PdmObject; + class PdmUiPropertyView; + + +//================================================================================================== +// +// +// +//================================================================================================== +class PdmUiPropertyDialog : public QDialog +{ + Q_OBJECT + +public: + PdmUiPropertyDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle); + +private: + void setupUi(); + +private: + QString m_windowTitle; + caf::PdmObject* m_pdmObject; + caf::PdmUiPropertyView* m_pdmUiPropertyView; +}; + + +} // end namespace caf From 0fbcc57473e02a120e232d010faf53b4e05b1cfb Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 12:50:39 +0100 Subject: [PATCH 069/130] Use caf property dialog and removed obsolete riuPreferencesDialog --- ApplicationCode/CMakeLists.txt | 2 - .../ProjectDataModel/RimUiTreeView.cpp | 15 ++--- .../UserInterface/RiuMainWindow.cpp | 8 +-- .../UserInterface/RiuPreferencesDialog.cpp | 67 ------------------- .../UserInterface/RiuPreferencesDialog.h | 49 -------------- 5 files changed, 11 insertions(+), 130 deletions(-) delete mode 100644 ApplicationCode/UserInterface/RiuPreferencesDialog.cpp delete mode 100644 ApplicationCode/UserInterface/RiuPreferencesDialog.h diff --git a/ApplicationCode/CMakeLists.txt b/ApplicationCode/CMakeLists.txt index d5fea80758..29c2db248b 100644 --- a/ApplicationCode/CMakeLists.txt +++ b/ApplicationCode/CMakeLists.txt @@ -43,7 +43,6 @@ set( APPLICATION_FILES set( USER_INTERFACE_FILES UserInterface/RiuCursors.cpp UserInterface/RiuMainWindow.cpp - UserInterface/RiuPreferencesDialog.cpp UserInterface/RiuResultInfoPanel.cpp UserInterface/RiuViewer.cpp UserInterface/RiuSimpleHistogramWidget.cpp @@ -98,7 +97,6 @@ set ( QT_MOC_HEADERS ProjectDataModel/RimMimeData.h UserInterface/RiuMainWindow.h - UserInterface/RiuPreferencesDialog.h UserInterface/RiuResultInfoPanel.h UserInterface/RiuViewer.h UserInterface/RiuProcessMonitor.h diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp b/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp index 272c7cca9b..690c0bdfa7 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp +++ b/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp @@ -19,6 +19,9 @@ //#include "RiaStdInclude.h" #include "cafPdmDocument.h" +#include "cafPdmFieldCvfColor.h" +#include "cafPdmFieldCvfMat4d.h" +#include "cafPdmUiPropertyDialog.h" #include #include @@ -37,7 +40,6 @@ #include "RimInputPropertyCollection.h" #include "RimExportInputPropertySettings.h" #include "RiaPreferences.h" -#include "RiuPreferencesDialog.h" #include "RifEclipseInputFileTools.h" #include "RimInputCase.h" #include "RimBinaryExportSettings.h" @@ -59,9 +61,6 @@ #include "RimWellPathCollection.h" #include "RimReservoirCellResultsCacher.h" #include "Rim3dOverlayInfoConfig.h" - -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" #include "RimProject.h" #include "RimOilField.h" #include "RimAnalysisModels.h" @@ -834,8 +833,8 @@ void RimUiTreeView::slotWriteInputProperty() exportSettings.fileName = outputFileName; } - RiuPreferencesDialog preferencesDialog(this, &exportSettings, "Export Eclipse Property to Text File"); - if (preferencesDialog.exec() == QDialog::Accepted) + caf::PdmUiPropertyDialog propertyDialog(this, &exportSettings, "Export Eclipse Property to Text File"); + if (propertyDialog.exec() == QDialog::Accepted) { bool isOk = RifEclipseInputFileTools::writePropertyToTextFile(exportSettings.fileName, inputReservoir->reservoirData(), 0, inputProperty->resultName, exportSettings.eclipseKeyword); if (isOk) @@ -887,8 +886,8 @@ void RimUiTreeView::slotWriteBinaryResultAsInputProperty() exportSettings.fileName = outputFileName; } - RiuPreferencesDialog preferencesDialog(this, &exportSettings, "Export Binary Eclipse Data to Text File"); - if (preferencesDialog.exec() == QDialog::Accepted) + caf::PdmUiPropertyDialog propertyDialog(this, &exportSettings, "Export Binary Eclipse Data to Text File"); + if (propertyDialog.exec() == QDialog::Accepted) { size_t timeStep = resultSlot->reservoirView()->currentTimeStep(); RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultSlot->porosityModel()); diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index 7210665d7a..943965cdb3 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -43,7 +43,6 @@ #include "RiuMultiCaseImportDialog.h" #include "RiaPreferences.h" -#include "RiuPreferencesDialog.h" #include "RigCaseCellResultsData.h" @@ -63,6 +62,7 @@ #include "RimCalcScript.h" #include "RimTools.h" #include "RiaRegressionTest.h" +#include "cafPdmUiPropertyDialog.h" @@ -1217,8 +1217,8 @@ void RiuMainWindow::slotShowPerformanceInfo(bool enable) void RiuMainWindow::slotEditPreferences() { RiaApplication* app = RiaApplication::instance(); - RiuPreferencesDialog preferencesDialog(this, app->preferences(), "Preferences"); - if (preferencesDialog.exec() == QDialog::Accepted) + caf::PdmUiPropertyDialog propertyDialog(this, app->preferences(), "Preferences"); + if (propertyDialog.exec() == QDialog::Accepted) { // Write preferences using QSettings and apply them to the application app->writeFieldsToApplicationStore(app->preferences()); @@ -1766,7 +1766,7 @@ void RiuMainWindow::slotShowRegressionTestDialog() RiaApplication* app = RiaApplication::instance(); app->readFieldsFromApplicationStore(®TestConfig); - RiuPreferencesDialog regressionTestDialog(this, ®TestConfig, "Regression Test"); + caf::PdmUiPropertyDialog regressionTestDialog(this, ®TestConfig, "Regression Test"); if (regressionTestDialog.exec() == QDialog::Accepted) { // Write preferences using QSettings and apply them to the application diff --git a/ApplicationCode/UserInterface/RiuPreferencesDialog.cpp b/ApplicationCode/UserInterface/RiuPreferencesDialog.cpp deleted file mode 100644 index 7a094776c8..0000000000 --- a/ApplicationCode/UserInterface/RiuPreferencesDialog.cpp +++ /dev/null @@ -1,67 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#include "RiaStdInclude.h" -#include "RiuPreferencesDialog.h" - -#include "cafAppEnum.h" -#include "cafPdmObject.h" - -#include "RimUiTreeModelPdm.h" -#include "cafPdmUiPropertyView.h" - - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RiuPreferencesDialog::RiuPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle) - : QDialog(parent) -{ - CVF_ASSERT(object); - - m_pdmObject = object; - m_windowTitle = windowTitle; - - setupUi(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuPreferencesDialog::setupUi() -{ - setWindowTitle(m_windowTitle); - - m_pdmUiPropertyView = new caf::PdmUiPropertyView(this); - - QVBoxLayout* dialogLayout = new QVBoxLayout; - setLayout(dialogLayout); - - dialogLayout->addWidget(m_pdmUiPropertyView); - m_pdmUiPropertyView->showProperties(m_pdmObject); - - // Buttons - QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - dialogLayout->addWidget(buttonBox); - - this->resize(400, 200); -} diff --git a/ApplicationCode/UserInterface/RiuPreferencesDialog.h b/ApplicationCode/UserInterface/RiuPreferencesDialog.h deleted file mode 100644 index 3751e108fb..0000000000 --- a/ApplicationCode/UserInterface/RiuPreferencesDialog.h +++ /dev/null @@ -1,49 +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 - -namespace caf -{ - class PdmObject; - class PdmUiPropertyView; -} - - -//================================================================================================== -// -// -// -//================================================================================================== -class RiuPreferencesDialog : public QDialog -{ - Q_OBJECT - -public: - RiuPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle); - -private: - void setupUi(); - -private: - QString m_windowTitle; - caf::PdmObject* m_pdmObject; - caf::PdmUiPropertyView* m_pdmUiPropertyView; -}; From a36d4c9b73d49efb085ee33c8626b920c9dceeb9 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 8 Nov 2013 10:34:05 +0100 Subject: [PATCH 070/130] Performance: Added OpenMP to mock models --- .../RigReservoirBuilderMock.cpp | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp index 0905772400..0afadeec18 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp @@ -134,10 +134,14 @@ void RigReservoirBuilderMock::appendCubeNodes(const cvf::Vec3d& min, const cvf:: void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCount, RigGridBase* hostGrid, std::vector& cells) { size_t activeCellIndex = 0; - size_t i; - for (i = 0; i < cellCount; i++) + long long i; + + cells.resize(cellCount); + +#pragma omp parallel for + for (i = 0; i < static_cast(cellCount); i++) { - RigCell riCell; + RigCell& riCell = cells[i]; riCell.setHostGrid(hostGrid); riCell.setCellIndex(i); @@ -164,8 +168,6 @@ void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCoun riCell.setActiveIndexInMatrixModel(activeCellIndex++); } */ - - cells.push_back(riCell); } } @@ -346,13 +348,15 @@ bool RigReservoirBuilderMock::dynamicResult(RigCaseData* eclipseCase, const QStr double scaleValue = 1.0 + resultIndex * 0.1; double offsetValue = 100 * resultIndex; - size_t k; - for (k = 0; k < eclipseCase->mainGrid()->cells().size(); k++) + values->resize(eclipseCase->mainGrid()->cells().size()); + +#pragma omp parallel for + for (long long k = 0; k < static_cast(eclipseCase->mainGrid()->cells().size()); k++) { RigCell& cell = eclipseCase->mainGrid()->cells()[k]; { double val = offsetValue + scaleValue * ( (stepIndex * 1000 + k) % eclipseCase->mainGrid()->cells().size() ); - values->push_back(val); + values->at(k) = val; } } From c74851bfff8d514dea84d888b8f897c5d1ee7ef4 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 8 Nov 2013 14:27:21 +0100 Subject: [PATCH 071/130] Performance: Reduce memory use for riGetPropertyData --- .../SocketInterface/RiaPropertyDataCommands.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index 40dc5d2efd..f31218d7e3 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -304,10 +304,10 @@ class RiaGetGridProperty: public RiaSocketCommand quint64 timestepCount = (quint64)requestedTimesteps.size(); socketStream << timestepCount; - size_t doubleValueCount = cellCountI * cellCountJ * cellCountK * timestepCount * sizeof(double); - std::vector values(doubleValueCount); size_t valueIdx = 0; + std::vector values(rigGrid->cellCount()); + for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); @@ -323,11 +323,11 @@ class RiaGetGridProperty: public RiaSocketCommand { cellValue = 0.0; } - values[valueIdx++] = cellValue; + values[cellIdx] = cellValue; } - } - server->currentClient()->write((const char *)values.data(), doubleValueCount); + server->currentClient()->write((const char *)values.data(), rigGrid->cellCount() * sizeof(double)); + } return true; } From 14521bd5b0e5c8b7c7dd01c7d9b038c15fcd94ea Mon Sep 17 00:00:00 2001 From: magnesj Date: Mon, 11 Nov 2013 14:36:59 +0100 Subject: [PATCH 072/130] Temporarily fixes for handling communication of more than 2GB data to/from octave --- OctavePlugin/riGetActiveCellProperty.cpp | 4 +- OctavePlugin/riGetGridProperty.cpp | 85 +++++++++++++++++++++--- OctavePlugin/riSetGridProperty.cpp | 13 ++-- 3 files changed, 87 insertions(+), 15 deletions(-) diff --git a/OctavePlugin/riGetActiveCellProperty.cpp b/OctavePlugin/riGetActiveCellProperty.cpp index a936b82d96..81b966f7d0 100644 --- a/OctavePlugin/riGetActiveCellProperty.cpp +++ b/OctavePlugin/riGetActiveCellProperty.cpp @@ -67,7 +67,7 @@ void getActiveCellProperty(Matrix& propertyFrames, const QString &serverName, qu for (size_t tIdx = 0; tIdx < timestepCount; ++tIdx) { - while (socket.bytesAvailable() < (int)byteCount) + while (socket.bytesAvailable() < (qint64)byteCount) { if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) { @@ -94,7 +94,7 @@ void getActiveCellProperty(Matrix& propertyFrames, const QString &serverName, qu } #endif - if ((int)byteCount != bytesRead) + if ((qint64)byteCount != bytesRead) { error("Could not read binary double data properly from socket"); octave_stdout << "Active cells: " << activeCellCount << ", Timesteps: " << timestepCount << std::endl; diff --git a/OctavePlugin/riGetGridProperty.cpp b/OctavePlugin/riGetGridProperty.cpp index 3771341644..3b1fbc589f 100644 --- a/OctavePlugin/riGetGridProperty.cpp +++ b/OctavePlugin/riGetGridProperty.cpp @@ -22,7 +22,7 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 QString command; command += "GetGridProperty " + QString::number(caseId) + " " + QString::number(gridIdx) + " " + propertyName + " " + porosityModel; - for (int i = 0; i < requestedTimeSteps.length(); ++i) + for (qint64 i = 0; i < requestedTimeSteps.length(); ++i) { if (i == 0) command += " "; command += QString::number(static_cast(requestedTimeSteps.elem(i)) - 1); // To make the index 0-based @@ -36,7 +36,7 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 // Get response. First wait for the header - while (socket.bytesAvailable() < (int)(4*sizeof(quint64))) + while (socket.bytesAvailable() < (qint64)(4*sizeof(quint64))) { if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) { @@ -48,6 +48,7 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 // Read sizes quint64 totalByteCount; + quint64 cellCountI; quint64 cellCountJ; quint64 cellCountK; @@ -59,6 +60,9 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 socketStream >> timestepCount; totalByteCount = cellCountI*cellCountJ*cellCountK*timestepCount*sizeof(double); + + qint64 timestepByteCount = cellCountI*cellCountJ*cellCountK*sizeof(double); + if (!(totalByteCount)) { error ("Could not find the requested data in ResInsight"); @@ -75,29 +79,92 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 propertyFrames.resize(dv); - // Wait for available data +#if 1 + // Wait for available data for each timestep, then read data for each timestep + + qint64 totalBytesRead = 0; + + for (size_t tIdx = 0; tIdx < timestepCount; ++tIdx) + { + qint64 bytesAvailable = socket.bytesAvailable() ; + + while ( bytesAvailable < (qint64)timestepByteCount) + { + if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) + { + error((("Waiting for timestep data number: ") + QString::number(tIdx)+ ": " + socket.errorString()).toLatin1().data()); + octave_stdout << "Cellcount: " << cellCountI*cellCountJ*cellCountK << ", Timesteps: " << timestepCount << std::endl; + return ; + } + + bytesAvailable = socket.bytesAvailable(); + + OCTAVE_QUIT; + } - while (socket.bytesAvailable() < (int)totalByteCount) + qint64 bytesRead = 0; + double * internalMatrixData = propertyFrames.fortran_vec(); + + // Raw data transfer. Faster. Not possible when dealing with coarsening + bytesRead = socket.read(((char*)(internalMatrixData)) + tIdx * timestepByteCount, timestepByteCount); + + if ((qint64)timestepByteCount != bytesRead) + { + error("Could not read binary double data properly from socket"); + octave_stdout << "Cellcount: " << cellCountI*cellCountJ*cellCountK << ", Timesteps count: " << timestepCount << std::endl; + octave_stdout << "Timestep : " << tIdx << std::endl; + } + + totalBytesRead += bytesRead; + + OCTAVE_QUIT; + } + + if ((qint64)totalByteCount != totalBytesRead) { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) + error("Could not read binary double data properly from socket"); + } + + #else + + // Wait for available data + qint64 bytesAvailable = socket.bytesAvailable() ; + + while (bytesAvailable < (qint64)totalByteCount) + { + octave_stdout << "Waiting for data. Has : " << bytesAvailable << " Needs :" << totalByteCount << std::endl; + if (!socket.waitForReadyRead(riOctavePlugin::shortTimeOutMilliSecs)) { - error(("Waiting for data : " + socket.errorString()).toLatin1().data()); - return ; + //error(("Waiting for data : " + socket.errorString()).toLatin1().data()); + //return ; } + + bytesAvailable = socket.bytesAvailable() ; OCTAVE_QUIT; } qint64 bytesRead = 0; double * internalMatrixData = propertyFrames.fortran_vec(); +#if 0 + + char* dataBuffer = new char[totalByteCount]; + bytesRead = socket.read(dataBuffer, totalByteCount); + + +#else + // Raw data transfer. Faster. bytesRead = socket.read((char*)(internalMatrixData ), totalByteCount); +#endif - if ((int)totalByteCount != bytesRead) + + if ((qint64)totalByteCount != bytesRead) { error("Could not read binary double data properly from socket"); } - + +#endif QString tmp = QString("riGetGridProperty : Read %1").arg(propertyName); if (caseId < 0) diff --git a/OctavePlugin/riSetGridProperty.cpp b/OctavePlugin/riSetGridProperty.cpp index 04773e8804..f5afe0a0f7 100644 --- a/OctavePlugin/riSetGridProperty.cpp +++ b/OctavePlugin/riSetGridProperty.cpp @@ -64,8 +64,13 @@ void setEclipseProperty(const NDArray& propertyFrames, const QString &hostName, socketStream << (qint64)singleTimeStepByteCount; const double* internalData = propertyFrames.fortran_vec(); - int dataWritten = socket.write((const char *)internalData, singleTimeStepByteCount*timeStepCount); - + qint64 dataWritten = 0; + + for (size_t tsIdx = 0; tsIdx < timeStepCount; ++tsIdx) + { + dataWritten += socket.write(((const char *)internalData) + tsIdx*singleTimeStepByteCount, singleTimeStepByteCount); + } + if (dataWritten == singleTimeStepByteCount*timeStepCount) { QString tmp = QString("riSetGridProperty : Wrote %1").arg(propertyName); @@ -92,8 +97,8 @@ void setEclipseProperty(const NDArray& propertyFrames, const QString &hostName, while(socket.bytesToWrite() && socket.state() == QAbstractSocket::ConnectedState) { - // octave_stdout << "Bytes to write: " << socket.bytesToWrite() << std::endl; - socket.waitForBytesWritten(riOctavePlugin::longTimeOutMilliSecs); + octave_stdout << "Bytes to write: " << socket.bytesToWrite() << std::endl << std::flush; + socket.waitForBytesWritten(2000); OCTAVE_QUIT; } From d751128fde2d4284d27e7dc4550f97c94b143cf8 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 3 Apr 2014 10:58:29 +0200 Subject: [PATCH 073/130] Added isCoarseningActive --- ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp | 8 ++++++++ ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h | 1 + 2 files changed, 9 insertions(+) diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp index bb0da770da..b58b17c5d4 100644 --- a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp @@ -193,6 +193,14 @@ void RigActiveCellInfo::clear() m_activeCellsBoundingBox.reset(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigActiveCellInfo::isCoarseningActive() const +{ + return m_globalCellResultCount != m_globalActiveCellCount; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h index 2719dbffb5..cbe11c9b8c 100644 --- a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h @@ -36,6 +36,7 @@ class RigActiveCellInfo : public cvf::Object size_t globalCellCount() const; size_t globalActiveCellCount() const; size_t globalCellResultCount() const; + bool isCoarseningActive() const; bool isActive(size_t globalCellIndex) const; size_t cellResultIndex(size_t globalCellIndex) const; From 0fc0b62f7d8d6e8609f59d40a51188f24dd3be21 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 3 Apr 2014 11:09:42 +0200 Subject: [PATCH 074/130] Updated use of buffer read --- OctavePlugin/riGetActiveCellInfo.cpp | 48 +++++++--------------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/OctavePlugin/riGetActiveCellInfo.cpp b/OctavePlugin/riGetActiveCellInfo.cpp index 824134e0f7..a7213a3697 100644 --- a/OctavePlugin/riGetActiveCellInfo.cpp +++ b/OctavePlugin/riGetActiveCellInfo.cpp @@ -1,7 +1,10 @@ #include +#include + #include #include "riSettings.h" +#include "riSocketTools.h" void getActiveCellInfo(int32NDArray& activeCellInfo, const QString &hostName, quint16 port, const qint64& caseId, const QString& porosityModel) @@ -43,59 +46,32 @@ void getActiveCellInfo(int32NDArray& activeCellInfo, const QString &hostName, qu // Read timestep count and blocksize quint64 columnCount; - quint64 byteCount; + quint64 byteCountForOneTimestep; size_t activeCellCount; socketStream >> columnCount; - socketStream >> byteCount; + socketStream >> byteCountForOneTimestep; - activeCellCount = byteCount / sizeof(qint32); + activeCellCount = byteCountForOneTimestep / sizeof(qint32); dim_vector dv (2, 1); dv(0) = activeCellCount; dv(1) = columnCount; activeCellInfo.resize(dv); - if (!(byteCount && columnCount)) + if (!(byteCountForOneTimestep && columnCount)) { error ("Could not find the requested data in ResInsight"); return; } - // Wait for available data for each column, then read data for each column - for (size_t tIdx = 0; tIdx < columnCount; ++tIdx) + qint32* internalMatrixData = (qint32*)activeCellInfo.fortran_vec()->mex_get_data(); + QStringList errorMessages; + if (!readBlockData(socket, (char*)(internalMatrixData), columnCount * byteCountForOneTimestep, errorMessages)) { - while (socket.bytesAvailable() < (int)byteCount) - { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) - { - QString errorMsg = QString("Waiting for column number: %1 of %2: %3").arg(tIdx).arg(columnCount).arg(socket.errorString()); - - error(errorMsg.toLatin1().data()); - octave_stdout << "Active cells: " << activeCellCount << ", Columns: " << columnCount << std::endl; - return ; - } - OCTAVE_QUIT; - } - - qint64 bytesRead = 0; - qint32* internalMatrixData = (qint32*)activeCellInfo.fortran_vec()->mex_get_data(); - -#if 1 // Use raw data transfer. Faster. - bytesRead = socket.read((char*)(internalMatrixData + tIdx * activeCellCount), byteCount); -#else - for (size_t cIdx = 0; cIdx < activeCellCount; ++cIdx) - { - socketStream >> internalMatrixData[tIdx * activeCellCount + cIdx]; - - if (socketStream.status() == QDataStream::Ok) bytesRead += sizeof(int); - } -#endif - - if ((int)byteCount != bytesRead) + for (int i = 0; i < errorMessages.size(); i++) { - error("Could not read binary double data properly from socket"); - octave_stdout << "Active cells: " << activeCellCount << ", Columns: " << columnCount << std::endl; + error(errorMessages[i].toLatin1().data()); } OCTAVE_QUIT; From 19ff7075d3450d1171a70253271b7bc6a8ea3350 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 10:30:11 +0100 Subject: [PATCH 075/130] Added serialization of pdm objects using QSettings --- Fwk/AppFwk/cafUserInterface/CMakeLists.txt | 2 + .../cafUserInterface/cafPdmSettings.cpp | 116 ++++++++++++++++++ Fwk/AppFwk/cafUserInterface/cafPdmSettings.h | 55 +++++++++ 3 files changed, 173 insertions(+) create mode 100644 Fwk/AppFwk/cafUserInterface/cafPdmSettings.cpp create mode 100644 Fwk/AppFwk/cafUserInterface/cafPdmSettings.h diff --git a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt index 59b3f8e273..b210e4a322 100644 --- a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt +++ b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt @@ -11,6 +11,7 @@ set( QOBJECT_HEADERS cafUiTreeModelPdm.h cafUiProcess.h + cafPdmSettings.h cafPdmUiLineEditor.h cafPdmUiCheckBoxEditor.h cafPdmUiComboBoxEditor.h @@ -39,6 +40,7 @@ endif() add_library( ${PROJECT_NAME} cafAboutDialog.cpp cafAboutDialog.h + cafPdmSettings.cpp cafPdmUiCheckBoxEditor.cpp cafPdmUiCheckBoxEditor.h cafPdmUiColorEditor.cpp diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmSettings.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmSettings.cpp new file mode 100644 index 0000000000..a8e3a3ba5c --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmSettings.cpp @@ -0,0 +1,116 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmSettings.h" +#include "cafPdmField.h" + +#include + + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Settings::readFieldsFromApplicationStore(caf::PdmObject* object) +{ + // Qt doc : + // + // Constructs a QSettings object for accessing settings of the application and organization + // set previously with a call to QCoreApplication::setOrganizationName(), + // QCoreApplication::setOrganizationDomain(), and QCoreApplication::setApplicationName(). + QSettings settings; + + QString prefix = object->classKeyword(); + if (!prefix.isEmpty()) + { + prefix += "/"; + } + + std::vector fields; + object->fields(fields); + size_t i; + for (i = 0; i < fields.size(); i++) + { + caf::PdmFieldHandle* fieldHandle = fields[i]; + + QString keywordWithPrefix = prefix + fieldHandle->keyword(); + if (settings.contains(keywordWithPrefix)) + { + QVariant val = settings.value(keywordWithPrefix); + fieldHandle->setValueFromUi(val); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Settings::writeFieldsToApplicationStore(caf::PdmObject* object) +{ + assert(object); + + // Qt doc : + // + // Constructs a QSettings object for accessing settings of the application and organization + // set previously with a call to QCoreApplication::setOrganizationName(), + // QCoreApplication::setOrganizationDomain(), and QCoreApplication::setApplicationName(). + QSettings settings; + + QString prefix = object->classKeyword(); + if (!prefix.isEmpty()) + { + prefix += "/"; + } + + std::vector fields; + object->fields(fields); + + size_t i; + for (i = 0; i < fields.size(); i++) + { + caf::PdmFieldHandle* fieldHandle = fields[i]; + + QString keywordWithPrefix = prefix + fieldHandle->keyword(); + settings.setValue(keywordWithPrefix, fieldHandle->uiValue()); + } +} + + +} // namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmSettings.h b/Fwk/AppFwk/cafUserInterface/cafPdmSettings.h new file mode 100644 index 0000000000..2342eacd71 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmSettings.h @@ -0,0 +1,55 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include + +namespace caf +{ + + class PdmObject; + +class Settings +{ +public: + static void readFieldsFromApplicationStore(caf::PdmObject* object); + static void writeFieldsToApplicationStore(caf::PdmObject* object); +}; + + +} // end namespace caf From 03516a8336a513e64df45d7d721151b98dc6cbf8 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 10:30:58 +0100 Subject: [PATCH 076/130] Added mock model settings --- .../ProjectDataModel/CMakeLists_files.cmake | 2 + .../ProjectDataModel/RimMockModelSettings.cpp | 73 +++++++++++++++++++ .../ProjectDataModel/RimMockModelSettings.h | 52 +++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp create mode 100644 ApplicationCode/ProjectDataModel/RimMockModelSettings.h diff --git a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake index d1eba17c50..4e0d185f37 100644 --- a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake @@ -46,6 +46,7 @@ ${CEE_CURRENT_LIST_DIR}RimCommandObject.h ${CEE_CURRENT_LIST_DIR}RimTools.h ${CEE_CURRENT_LIST_DIR}RimFault.h ${CEE_CURRENT_LIST_DIR}RimFaultCollection.h +${CEE_CURRENT_LIST_DIR}RimMockModelSettings.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -90,6 +91,7 @@ ${CEE_CURRENT_LIST_DIR}RimCommandObject.cpp ${CEE_CURRENT_LIST_DIR}RimTools.cpp ${CEE_CURRENT_LIST_DIR}RimFault.cpp ${CEE_CURRENT_LIST_DIR}RimFaultCollection.cpp +${CEE_CURRENT_LIST_DIR}RimMockModelSettings.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp b/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp new file mode 100644 index 0000000000..3e032f107a --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimMockModelSettings.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 "RiaStdInclude.h" + + +#include "RimMockModelSettings.h" + + + + +CAF_PDM_SOURCE_INIT(RimMockModelSettings, "MockModelSettings"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMockModelSettings::RimMockModelSettings() +{ + CAF_PDM_InitObject("Mock Model Settings", "", "", ""); + + CAF_PDM_InitField(&cellCountX, "CellCountX", quint64(100), "Cell Count X", "", "", ""); + CAF_PDM_InitField(&cellCountY, "CellCountY", quint64(100), "Cell Count Y", "", "", ""); + CAF_PDM_InitField(&cellCountZ, "CellCountZ", quint64(100), "Cell Count Z", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&totalCellCount, "TotalCellCount", "Total Cell Count", "", "", ""); + totalCellCount.setUiReadOnly(true); + + CAF_PDM_InitField(&resultCount, "ResultCount", quint64(3), "Result Count", "", "", ""); + CAF_PDM_InitField(&timeStepCount, "TimeStepCount", quint64(10), "Time Step Count", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMockModelSettings::~RimMockModelSettings() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMockModelSettings::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + totalCellCount = cellCountX * cellCountY * cellCountZ; + totalCellCount.updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMockModelSettings::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + caf::PdmUiGroup* gridSizeGroup = uiOrdering.addNewGroup("Grid size"); + gridSizeGroup->add(&cellCountX); + gridSizeGroup->add(&cellCountY); + gridSizeGroup->add(&cellCountZ); + gridSizeGroup->add(&totalCellCount); +} diff --git a/ApplicationCode/ProjectDataModel/RimMockModelSettings.h b/ApplicationCode/ProjectDataModel/RimMockModelSettings.h new file mode 100644 index 0000000000..64d1beac66 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimMockModelSettings.h @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPointer.h" + + +//================================================================================================== +/// +/// +//================================================================================================== +class RimMockModelSettings : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + + RimMockModelSettings(); + virtual ~RimMockModelSettings(); + + caf::PdmField cellCountX; + caf::PdmField cellCountY; + caf::PdmField cellCountZ; + + caf::PdmField totalCellCount; + + caf::PdmField resultCount; + caf::PdmField timeStepCount; + + + virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); + + virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ); + +}; From 343dba02f86581ac879144ea1073fa1cdc89c806 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 28 Oct 2013 10:31:46 +0100 Subject: [PATCH 077/130] Added flag to control adding of well data --- .../ReservoirDataModel/RigReservoirBuilderMock.cpp | 11 ++++++++++- .../ReservoirDataModel/RigReservoirBuilderMock.h | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp index 0afadeec18..f62e9c90c6 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp @@ -34,6 +34,7 @@ RigReservoirBuilderMock::RigReservoirBuilderMock() m_resultCount = 0; m_timeStepCount = 0; m_gridPointDimensions = cvf::Vec3st::ZERO; + m_enableWellData = true; } //-------------------------------------------------------------------------------------------------- @@ -248,7 +249,10 @@ void RigReservoirBuilderMock::populateReservoir(RigCaseData* eclipseCase) eclipseCase->mainGrid()->setGridPointDimensions(m_gridPointDimensions); - addWellData(eclipseCase, eclipseCase->mainGrid()); + if (m_enableWellData) + { + addWellData(eclipseCase, eclipseCase->mainGrid()); + } addFaults(eclipseCase); @@ -525,3 +529,8 @@ void RigReservoirBuilderMock::addFaults(RigCaseData* eclipseCase) grid->setFaults(faults); } +void RigReservoirBuilderMock::enableWellData(bool enableWellData) +{ + m_enableWellData = false; +} + diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h index 619fb0069a..7076027264 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h @@ -48,6 +48,7 @@ class RigReservoirBuilderMock void setWorldCoordinates(cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate); void setGridPointDimensions(const cvf::Vec3st& gridPointDimensions); void setResultInfo(size_t resultCount, size_t timeStepCount); + void enableWellData(bool enableWellData); size_t resultCount() const { return m_resultCount; } size_t timeStepCount() const { return m_timeStepCount; } @@ -91,6 +92,7 @@ class RigReservoirBuilderMock cvf::Vec3st m_gridPointDimensions; size_t m_resultCount; size_t m_timeStepCount; + bool m_enableWellData; std::vector m_localGridRefinements; }; From 7a07b2926e6bfe7c3cb376be5fefad7813d17d00 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 1 Apr 2014 13:02:52 +0200 Subject: [PATCH 078/130] Added flag to control how to do IO with sockets --- .../Application/RiaPreferences.cpp | 1 + ApplicationCode/Application/RiaPreferences.h | 2 + .../SocketInterface/RiaGeometryCommands.cpp | 62 +++++++++++++++---- .../RiaPropertyDataCommands.cpp | 55 ++++++++++++---- 4 files changed, 96 insertions(+), 24 deletions(-) diff --git a/ApplicationCode/Application/RiaPreferences.cpp b/ApplicationCode/Application/RiaPreferences.cpp index 3e45619055..5c060c7031 100644 --- a/ApplicationCode/Application/RiaPreferences.cpp +++ b/ApplicationCode/Application/RiaPreferences.cpp @@ -60,6 +60,7 @@ RiaPreferences::RiaPreferences(void) CAF_PDM_InitField(&autocomputeDepthRelatedProperties,"autocomputeDepth", true, "DEPTH related properties", "", "DEPTH, DX, DY, DZ, TOP, BOTTOM", ""); CAF_PDM_InitField(&readFaultData, "readFaultData", true, "Read fault data", "", "", ""); + CAF_PDM_InitField(&useStreamTransfer, "useStreamTransfer", true, "Use stream transfer to Octave", "", "", ""); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Application/RiaPreferences.h b/ApplicationCode/Application/RiaPreferences.h index 4623599926..5fcc691d3c 100644 --- a/ApplicationCode/Application/RiaPreferences.h +++ b/ApplicationCode/Application/RiaPreferences.h @@ -60,6 +60,8 @@ class RiaPreferences : public caf::PdmObject caf::PdmField readFaultData; + caf::PdmField useStreamTransfer; + protected: virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); diff --git a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp index 2ec5878cb6..413f4791bc 100644 --- a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp @@ -34,6 +34,8 @@ #include "RigCaseCellResultsData.h" #include +#include "RiaApplication.h" +#include "RiaPreferences.h" //-------------------------------------------------------------------------------------------------- @@ -241,32 +243,66 @@ class RiaGetCellCorners : public RiaSocketCommand // dv(3) = 8; // dv(4) = 3; - std::vector cellCornerValues(doubleValueCount); - cvf::Vec3d cornerVerts[8]; - quint64 coordCount = 0; - for (int coordIdx = 0; coordIdx < 3; coordIdx++) + cvf::Timer timer; + + if (RiaApplication::instance()->preferences()->useStreamTransfer()) { - for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) + cvf::Vec3d cornerVerts[8]; + for (int coordIdx = 0; coordIdx < 3; coordIdx++) { - size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; + for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) + { + size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; + + for (size_t k = 0; k < cellCountK; k++) + { + for (size_t j = 0; j < cellCountJ; j++) + { + for (size_t i = 0; i < cellCountI; i++) + { + size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); + rigGrid->cellCornerVertices(localCellIdx, cornerVerts); - for (size_t k = 0; k < cellCountK; k++) + socketStream << cornerVerts[cornerIndexMapping][coordIdx]; + } + } + } + } + } + } + else + { + std::vector cellCornerValues(doubleValueCount); + cvf::Vec3d cornerVerts[8]; + quint64 coordCount = 0; + for (int coordIdx = 0; coordIdx < 3; coordIdx++) + { + for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) { - for (size_t j = 0; j < cellCountJ; j++) + size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; + + for (size_t k = 0; k < cellCountK; k++) { - for (size_t i = 0; i < cellCountI; i++) + for (size_t j = 0; j < cellCountJ; j++) { - size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); - rigGrid->cellCornerVertices(localCellIdx, cornerVerts); + for (size_t i = 0; i < cellCountI; i++) + { + size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); + rigGrid->cellCornerVertices(localCellIdx, cornerVerts); - cellCornerValues[coordCount++] = cornerVerts[cornerIndexMapping][coordIdx]; + cellCornerValues[coordCount++] = cornerVerts[cornerIndexMapping][coordIdx]; + } } } } } + server->currentClient()->write((const char *)cellCornerValues.data(), byteCount); } - server->currentClient()->write((const char *)cellCornerValues.data(), byteCount); + double totalTimeMS = timer.time() * 1000.0; + QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); + + server->errorMessageDialog()->showMessage(resultInfo); return true; } diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index f31218d7e3..4fa6a4f841 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -40,6 +40,8 @@ #include "Rim3dOverlayInfoConfig.h" #include +#include "RiaApplication.h" +#include "RiaPreferences.h" //-------------------------------------------------------------------------------------------------- @@ -305,30 +307,61 @@ class RiaGetGridProperty: public RiaSocketCommand socketStream << timestepCount; size_t valueIdx = 0; - - std::vector values(rigGrid->cellCount()); + cvf::Timer timer; - for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) + if (RiaApplication::instance()->preferences()->useStreamTransfer()) { - cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); - if (cellCenterDataAccessObject.isNull()) + for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { - continue; + cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); + if (cellCenterDataAccessObject.isNull()) + { + continue; + } + + for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) + { + double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); + if (cellValue == HUGE_VAL) + { + cellValue = 0.0; + } + + socketStream << cellValue; + } } + } + else + { - for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) + std::vector values(rigGrid->cellCount()); + for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { - double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); - if (cellValue == HUGE_VAL) + cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); + if (cellCenterDataAccessObject.isNull()) { - cellValue = 0.0; + continue; + } + + for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) + { + double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); + if (cellValue == HUGE_VAL) + { + cellValue = 0.0; + } + values[valueIdx++] = cellValue; } - values[cellIdx] = cellValue; } server->currentClient()->write((const char *)values.data(), rigGrid->cellCount() * sizeof(double)); } + double totalTimeMS = timer.time() * 1000.0; + QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); + + server->errorMessageDialog()->showMessage(resultInfo); + return true; } }; From e5248683f09e2f48ae1e676926dd623d4f591a46 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 1 Apr 2014 15:31:13 +0200 Subject: [PATCH 079/130] Added block write to socket tools --- .../Application/RiaPreferences.cpp | 1 + ApplicationCode/Application/RiaPreferences.h | 1 + .../SocketInterface/RiaCaseInfoCommands.cpp | 9 +++- .../SocketInterface/RiaGeometryCommands.cpp | 10 ++-- .../RiaPropertyDataCommands.cpp | 5 +- .../SocketInterface/RiaSocketTools.cpp | 47 +++++++++++++++++++ .../SocketInterface/RiaSocketTools.h | 3 ++ 7 files changed, 67 insertions(+), 9 deletions(-) diff --git a/ApplicationCode/Application/RiaPreferences.cpp b/ApplicationCode/Application/RiaPreferences.cpp index 5c060c7031..793c2ffc9c 100644 --- a/ApplicationCode/Application/RiaPreferences.cpp +++ b/ApplicationCode/Application/RiaPreferences.cpp @@ -61,6 +61,7 @@ RiaPreferences::RiaPreferences(void) CAF_PDM_InitField(&readFaultData, "readFaultData", true, "Read fault data", "", "", ""); CAF_PDM_InitField(&useStreamTransfer, "useStreamTransfer", true, "Use stream transfer to Octave", "", "", ""); + CAF_PDM_InitField(&blockSize, "blockSize", 10000, "blockSize", "", "", ""); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Application/RiaPreferences.h b/ApplicationCode/Application/RiaPreferences.h index 5fcc691d3c..785eccf6d6 100644 --- a/ApplicationCode/Application/RiaPreferences.h +++ b/ApplicationCode/Application/RiaPreferences.h @@ -61,6 +61,7 @@ class RiaPreferences : public caf::PdmObject caf::PdmField readFaultData; caf::PdmField useStreamTransfer; + caf::PdmField blockSize; protected: virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); diff --git a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp index 201267dfb0..e6444f314d 100644 --- a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp @@ -16,9 +16,12 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RiaStdInclude.h" + #include "RiaSocketCommand.h" #include "RiaSocketServer.h" #include "RiaSocketTools.h" +#include "RiaApplication.h" +#include "RiaPreferences.h" #include "RimReservoirView.h" #include "RimResultSlot.h" @@ -28,8 +31,8 @@ #include "RimWellCollection.h" #include "Rim3dOverlayInfoConfig.h" #include "RimReservoirCellResultsCacher.h" - #include "RimCase.h" + #include "RigCaseData.h" #include "RigCaseCellResultsData.h" @@ -37,6 +40,7 @@ + //-------------------------------------------------------------------------------------------------- /// OBSOLETE, to be deleted //-------------------------------------------------------------------------------------------------- @@ -133,7 +137,8 @@ class RiaGetActiveCellInfo: public RiaSocketCommand for (size_t tIdx = 0; tIdx < columnCount; ++tIdx) { #if 1 // Write data as raw bytes, fast but does not handle byteswapping - server->currentClient()->write((const char *)activeCellInfo[tIdx].data(), timestepByteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)activeCellInfo[tIdx].data(), timestepByteCount); + #else // Write data using QDataStream, does byteswapping for us. Must use QDataStream on client as well for (size_t cIdx = 0; cIdx < activeCellInfo[tIdx].size(); ++cIdx) { diff --git a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp index 413f4791bc..5a3c8bc8b7 100644 --- a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp @@ -38,6 +38,7 @@ #include "RiaPreferences.h" + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -108,7 +109,7 @@ class RiaGetCellCenters : public RiaSocketCommand CVF_ASSERT(coordCount == doubleValueCount); - server->currentClient()->write((const char *)cellCenterValues.data(), byteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCenterValues.data(), byteCount); return true; } @@ -181,7 +182,7 @@ class RiaGetActiveCellCenters : public RiaSocketCommand quint64 byteCount = doubleValueCount * sizeof(double); socketStream << byteCount; - server->currentClient()->write((const char *)cellCenterValues.data(), byteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCenterValues.data(), byteCount); return true; } @@ -296,7 +297,8 @@ class RiaGetCellCorners : public RiaSocketCommand } } } - server->currentClient()->write((const char *)cellCornerValues.data(), byteCount); + + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCornerValues.data(), byteCount); } double totalTimeMS = timer.time() * 1000.0; @@ -381,7 +383,7 @@ class RiaGetActiveCellCorners : public RiaSocketCommand quint64 byteCount = doubleValueCount * sizeof(double); socketStream << byteCount; - server->currentClient()->write((const char *)cellCornerValues.data(), byteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCornerValues.data(), byteCount); return true; } diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index 4fa6a4f841..00210e4e21 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -334,7 +334,6 @@ class RiaGetGridProperty: public RiaSocketCommand else { - std::vector values(rigGrid->cellCount()); for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); @@ -343,6 +342,7 @@ class RiaGetGridProperty: public RiaSocketCommand continue; } + std::vector values(rigGrid->cellCount()); for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) { double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); @@ -352,9 +352,8 @@ class RiaGetGridProperty: public RiaSocketCommand } values[valueIdx++] = cellValue; } + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), values.size() * sizeof(double)); } - - server->currentClient()->write((const char *)values.data(), rigGrid->cellCount() * sizeof(double)); } double totalTimeMS = timer.time() * 1000.0; diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.cpp b/ApplicationCode/SocketInterface/RiaSocketTools.cpp index cc53f26824..4ad720d2a9 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketTools.cpp @@ -16,6 +16,10 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RiaStdInclude.h" + +#include "RiaApplication.h" +#include "RiaPreferences.h" + #include "RiaSocketTools.h" #include "RiaSocketServer.h" #include "RimCase.h" @@ -34,6 +38,8 @@ #include "RimInputPropertyCollection.h" +#include + //-------------------------------------------------------------------------------------------------- /// @@ -98,4 +104,45 @@ void RiaSocketTools::getCaseInfoFromCase(RimCase* rimCase, qint64& caseId, QStri } } +bool RiaSocketTools::writeBlockData(RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite) +{ + cvf::Timer timer; + + quint64 bytesWritten = 0; + int blockCount = 0; + + quint64 maxBlockSize = RiaApplication::instance()->preferences()->blockSize(); + + while (bytesWritten < bytesToWrite) + { + quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize); + + quint64 actuallyBytesWritten = socket->write(data + bytesWritten, byteCountToWrite); + if (actuallyBytesWritten == -1) + { + if (server) + { + QString errorMessage = "Error detected when writing data, error string from socket : \n" + socket->errorString(); + + server->errorMessageDialog()->showMessage(errorMessage); + } + + return false; + } + + bytesWritten += actuallyBytesWritten; + + blockCount++; + } + + if (server) + { + double totalTimeMS = timer.time() * 1000.0; + QString resultInfo = QString("Total time '%1 ms'\nTotal bytes written . %2\nNumber of blocks : %3\nBlock size : %4").arg(totalTimeMS).arg(bytesWritten).arg(blockCount).arg(maxBlockSize); + + server->errorMessageDialog()->showMessage(resultInfo); + } + + return true; +} diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.h b/ApplicationCode/SocketInterface/RiaSocketTools.h index 1baeb5a9fc..b331799e2e 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.h +++ b/ApplicationCode/SocketInterface/RiaSocketTools.h @@ -17,6 +17,7 @@ class RimCase; class RiaSocketServer; +class QTcpSocket; #define PMonLog( MessageString ) RiuMainWindow::instance()->processMonitor()->addStringToLog( MessageString ); @@ -25,4 +26,6 @@ class RiaSocketTools public: static RimCase* findCaseFromArgs(RiaSocketServer* server, const QList& args); static void getCaseInfoFromCase(RimCase* rimCase, qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId); + + static bool writeBlockData(RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite); }; From c2f80f402df523422a1c5ff37605c402c0612a74 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 1 Apr 2014 15:36:08 +0200 Subject: [PATCH 080/130] Fixed used on unsigned --- ApplicationCode/SocketInterface/RiaSocketTools.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.cpp b/ApplicationCode/SocketInterface/RiaSocketTools.cpp index 4ad720d2a9..0f645450f9 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketTools.cpp @@ -113,12 +113,13 @@ bool RiaSocketTools::writeBlockData(RiaSocketServer* server, QTcpSocket* socket, quint64 maxBlockSize = RiaApplication::instance()->preferences()->blockSize(); + while (bytesWritten < bytesToWrite) { quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize); - quint64 actuallyBytesWritten = socket->write(data + bytesWritten, byteCountToWrite); - if (actuallyBytesWritten == -1) + qint64 actuallyBytesWritten = socket->write(data + bytesWritten, byteCountToWrite); + if (actuallyBytesWritten < 0) { if (server) { From 492d86c39f4eb5ec01c4732907237c2b4f116c61 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Wed, 2 Apr 2014 08:55:26 +0200 Subject: [PATCH 081/130] Added block read from socket --- .../SocketInterface/RiaSocketTools.cpp | 43 +++++++++++++++++++ .../SocketInterface/RiaSocketTools.h | 1 + OctavePlugin/riGetCellCorners.cpp | 17 ++++++++ 3 files changed, 61 insertions(+) diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.cpp b/ApplicationCode/SocketInterface/RiaSocketTools.cpp index 0f645450f9..64cc8e0c11 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketTools.cpp @@ -147,3 +147,46 @@ bool RiaSocketTools::writeBlockData(RiaSocketServer* server, QTcpSocket* socket, return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiaSocketTools::readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages) +{ + quint64 bytesRead = 0; + int blockCount = 0; + + quint64 maxBlockSize = RiaApplication::instance()->preferences()->blockSize(); + + while (bytesRead < bytesToRead) + { + if (socket.bytesAvailable()) + { + quint64 byteCountToRead = qMin(bytesToRead - bytesRead, maxBlockSize); + + qint64 actuallyBytesRead = socket.read(data + bytesRead, byteCountToRead); + if (actuallyBytesRead < 0) + { + errorMessages.push_back("Error detected when writing data, error string from socket"); + errorMessages.push_back(socket.errorString()); + + return false; + } + + bytesRead += actuallyBytesRead; + blockCount++; + } + else + { + if (!socket.waitForReadyRead()) + { + errorMessages.push_back("Waited for data for %1 milli seconds."); + errorMessages.push_back(socket.errorString()); + + return false; + } + } + } + + return true; +} + diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.h b/ApplicationCode/SocketInterface/RiaSocketTools.h index b331799e2e..5a24731237 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.h +++ b/ApplicationCode/SocketInterface/RiaSocketTools.h @@ -28,4 +28,5 @@ class RiaSocketTools static void getCaseInfoFromCase(RimCase* rimCase, qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId); static bool writeBlockData(RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite); + static bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages); }; diff --git a/OctavePlugin/riGetCellCorners.cpp b/OctavePlugin/riGetCellCorners.cpp index ee8f810239..af659079c0 100644 --- a/OctavePlugin/riGetCellCorners.cpp +++ b/OctavePlugin/riGetCellCorners.cpp @@ -1,7 +1,10 @@ #include +#include + #include #include "riSettings.h" +#include "../ApplicationCode/SocketInterface/RiaSocketTools.h" void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 port, const qint32& caseId, const quint32& gridIndex) @@ -67,7 +70,20 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 dv(4) = 3; cellCornerValues.resize(dv); + double* internalMatrixData = cellCornerValues.fortran_vec(); + QStringList errorMessages; + if (!RiaSocketTools::readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) + { + for (int i = 0; i < errorMessages.size(); i++) + { + error(errorMessages[i].toLatin1().data()); + } + + OCTAVE_QUIT; + } + + /* while (socket.bytesAvailable() < (qint64)(byteCount)) { if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) @@ -97,6 +113,7 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 } #endif + */ return; } From 1fd4c56a46b3e4007ec28cef05fc67a2b8eca347 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Wed, 2 Apr 2014 09:52:02 +0200 Subject: [PATCH 082/130] Moved Octave socket reading into riSocketTools --- OctavePlugin/riGetCellCorners.cpp | 8 ++++-- OctavePlugin/riGetCurrentCase.cpp | 1 + OctavePlugin/riSocketTools.h | 46 +++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 OctavePlugin/riSocketTools.h diff --git a/OctavePlugin/riGetCellCorners.cpp b/OctavePlugin/riGetCellCorners.cpp index af659079c0..f5e3b2c356 100644 --- a/OctavePlugin/riGetCellCorners.cpp +++ b/OctavePlugin/riGetCellCorners.cpp @@ -4,7 +4,9 @@ #include #include "riSettings.h" -#include "../ApplicationCode/SocketInterface/RiaSocketTools.h" +#include "riSocketTools.h" + + void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 port, const qint32& caseId, const quint32& gridIndex) @@ -72,7 +74,7 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 double* internalMatrixData = cellCornerValues.fortran_vec(); QStringList errorMessages; - if (!RiaSocketTools::readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) + if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) { for (int i = 0; i < errorMessages.size(); i++) { @@ -82,6 +84,8 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 OCTAVE_QUIT; } + octave_stdout << "Bytes count processed : " << byteCount << std::endl; + /* while (socket.bytesAvailable() < (qint64)(byteCount)) diff --git a/OctavePlugin/riGetCurrentCase.cpp b/OctavePlugin/riGetCurrentCase.cpp index 80b0ffe4ac..88cc38088d 100644 --- a/OctavePlugin/riGetCurrentCase.cpp +++ b/OctavePlugin/riGetCurrentCase.cpp @@ -3,6 +3,7 @@ #include #include "riSettings.h" +#include "riSocketTools.h" void getCurrentCase(qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId, const QString &hostName, quint16 port) { diff --git a/OctavePlugin/riSocketTools.h b/OctavePlugin/riSocketTools.h new file mode 100644 index 0000000000..7d01381668 --- /dev/null +++ b/OctavePlugin/riSocketTools.h @@ -0,0 +1,46 @@ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages) +{ + quint64 bytesRead = 0; + int blockCount = 0; + + quint64 maxBlockSize = 100000; + + while (bytesRead < bytesToRead) + { + if (socket.bytesAvailable()) + { + quint64 byteCountToRead = qMin(bytesToRead - bytesRead, maxBlockSize); + + qint64 actuallyBytesRead = socket.read(data + bytesRead, byteCountToRead); + if (actuallyBytesRead < 0) + { + errorMessages.push_back("Error detected when writing data, error string from socket"); + errorMessages.push_back(socket.errorString()); + + return false; + } + + bytesRead += actuallyBytesRead; + + octave_stdout << "Bytes read " << bytesRead << " of total " << bytesToRead << std::endl; + + blockCount++; + } + else + { + if (!socket.waitForReadyRead()) + { + errorMessages.push_back("Waited for data for %1 milli seconds."); + errorMessages.push_back(socket.errorString()); + + return false; + } + } + } + + return true; +} From 414384804e64679f0576fa02982054f1271a3800 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 3 Apr 2014 08:16:15 +0200 Subject: [PATCH 083/130] Moved socket max byte count to riSettings Added header files to cmake --- OctavePlugin/CMakeLists.txt | 5 ++++- OctavePlugin/riSettings.h | 2 ++ OctavePlugin/riSocketTools.h | 38 ++++++++++++++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/OctavePlugin/CMakeLists.txt b/OctavePlugin/CMakeLists.txt index 68a4b588d3..7a11e18ab9 100644 --- a/OctavePlugin/CMakeLists.txt +++ b/OctavePlugin/CMakeLists.txt @@ -141,7 +141,10 @@ if (RESINSIGHT_OCTAVE_PLUGIN_QMAKE AND RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE) "${CMAKE_CURRENT_BINARY_DIR}/riGetWellNames.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetWellStatus.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetWellCells.oct" - SOURCES ${CPP_SOURCES} + SOURCES + ${CPP_SOURCES} + riSocketTools.h + riSettings.h ) diff --git a/OctavePlugin/riSettings.h b/OctavePlugin/riSettings.h index bc7220e845..5765244a6d 100644 --- a/OctavePlugin/riSettings.h +++ b/OctavePlugin/riSettings.h @@ -24,6 +24,8 @@ namespace riOctavePlugin const int shortTimeOutMilliSecs = 5000; const int longTimeOutMilliSecs = 6000000; + const int socketMaxByteCount = 100000; + // Octave data structure : CaseInfo char caseInfo_CaseId[] = "CaseId"; char caseInfo_CaseName[] = "CaseName"; diff --git a/OctavePlugin/riSocketTools.h b/OctavePlugin/riSocketTools.h index 7d01381668..63cc24d890 100644 --- a/OctavePlugin/riSocketTools.h +++ b/OctavePlugin/riSocketTools.h @@ -7,7 +7,7 @@ bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringL quint64 bytesRead = 0; int blockCount = 0; - quint64 maxBlockSize = 100000; + quint64 maxBlockSize = riOctavePlugin::socketMaxByteCount; while (bytesRead < bytesToRead) { @@ -18,7 +18,7 @@ bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringL qint64 actuallyBytesRead = socket.read(data + bytesRead, byteCountToRead); if (actuallyBytesRead < 0) { - errorMessages.push_back("Error detected when writing data, error string from socket"); + errorMessages.push_back("Error detected when reading data, error string from socket :"); errorMessages.push_back(socket.errorString()); return false; @@ -41,6 +41,40 @@ bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringL } } } + + octave_stdout << "Bytes read " << bytesToRead << std::endl; + + return true; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool writeBlockData(QTcpSocket& socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages) +{ + quint64 bytesWritten = 0; + int blockCount = 0; + + quint64 maxBlockSize = riOctavePlugin::socketMaxByteCount; + + while (bytesWritten < bytesToWrite) + { + quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize); + + qint64 actuallyBytesWritten = socket.write(data + bytesWritten, byteCountToWrite); + if (actuallyBytesWritten < 0) + { + errorMessages.push_back("Error detected when writing data, error string from socket"); + errorMessages.push_back(socket.errorString()); + + return false; + } + + bytesWritten += actuallyBytesWritten; + + blockCount++; + } return true; } From b16536c9b0165dc0fbbea9e6c2eacca511355155 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 3 Apr 2014 10:41:27 +0200 Subject: [PATCH 084/130] Use socket block read/write for geometry data --- .../SocketInterface/RiaGeometryCommands.cpp | 127 ++++++++---------- OctavePlugin/riGetActiveCellCenters.cpp | 23 ++-- OctavePlugin/riGetActiveCellCorners.cpp | 23 ++-- OctavePlugin/riGetCellCenters.cpp | 37 ++--- OctavePlugin/riGetCellCorners.cpp | 35 ----- 5 files changed, 82 insertions(+), 163 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp index 5a3c8bc8b7..2ca72a655d 100644 --- a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp @@ -87,11 +87,14 @@ class RiaGetCellCenters : public RiaSocketCommand // dv(2) = cellCountK; // dv(3) = 3; - std::vector cellCenterValues(doubleValueCount); cvf::Vec3d cornerVerts[8]; - quint64 coordCount = 0; + size_t blockByteCount = cellCount * sizeof(double); + std::vector doubleValues(blockByteCount); + for (int coordIdx = 0; coordIdx < 3; coordIdx++) { + quint64 valueIndex = 0; + for (size_t k = 0; k < cellCountK; k++) { for (size_t j = 0; j < cellCountJ; j++) @@ -101,15 +104,15 @@ class RiaGetCellCenters : public RiaSocketCommand size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); cvf::Vec3d center = rigGrid->cell(localCellIdx).center(); - cellCenterValues[coordCount++] = center[coordIdx]; + doubleValues[valueIndex++] = center[coordIdx]; } } } - } - CVF_ASSERT(coordCount == doubleValueCount); + CVF_ASSERT(valueIndex == cellCount); - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCenterValues.data(), byteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); + } return true; } @@ -152,6 +155,11 @@ class RiaGetActiveCellCenters : public RiaSocketCommand size_t activeCellCount = actCellInfo->globalActiveCellCount(); size_t doubleValueCount = activeCellCount * 3; + socketStream << (quint64)activeCellCount; + quint64 byteCount = doubleValueCount * sizeof(double); + socketStream << byteCount; + + // This structure is supposed to be received by Octave using a NDArray. The ordering of this loop is // defined by the ordering of the receiving NDArray // @@ -162,27 +170,25 @@ class RiaGetActiveCellCenters : public RiaSocketCommand // dv(0) = coordCount; // dv(1) = 3; - std::vector cellCenterValues(doubleValueCount); - quint64 coordCount = 0; + size_t blockByteCount = activeCellCount * sizeof(double); + std::vector doubleValues(blockByteCount); + for (int coordIdx = 0; coordIdx < 3; coordIdx++) { + quint64 valueIndex = 0; + for (size_t globalCellIdx = 0; globalCellIdx < mainGrid->cells().size(); globalCellIdx++) { if (!actCellInfo->isActive(globalCellIdx)) continue; cvf::Vec3d center = mainGrid->cells()[globalCellIdx].center(); - cellCenterValues[coordCount++] = center[coordIdx]; + doubleValues[valueIndex++] = center[coordIdx]; } - } - - CVF_ASSERT(coordCount == doubleValueCount); - socketStream << (quint64)activeCellCount; - quint64 byteCount = doubleValueCount * sizeof(double); - socketStream << byteCount; - - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCenterValues.data(), byteCount); + CVF_ASSERT(valueIndex == activeCellCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); + } return true; } @@ -244,67 +250,37 @@ class RiaGetCellCorners : public RiaSocketCommand // dv(3) = 8; // dv(4) = 3; - cvf::Timer timer; + cvf::Vec3d cornerVerts[8]; + size_t blockByteCount = cellCount * sizeof(double); + std::vector doubleValues(blockByteCount); - if (RiaApplication::instance()->preferences()->useStreamTransfer()) + for (int coordIdx = 0; coordIdx < 3; coordIdx++) { - cvf::Vec3d cornerVerts[8]; - for (int coordIdx = 0; coordIdx < 3; coordIdx++) + for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) { - for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) - { - size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; + size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; - for (size_t k = 0; k < cellCountK; k++) - { - for (size_t j = 0; j < cellCountJ; j++) - { - for (size_t i = 0; i < cellCountI; i++) - { - size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); - rigGrid->cellCornerVertices(localCellIdx, cornerVerts); + quint64 valueIndex = 0; - socketStream << cornerVerts[cornerIndexMapping][coordIdx]; - } - } - } - } - } - } - else - { - std::vector cellCornerValues(doubleValueCount); - cvf::Vec3d cornerVerts[8]; - quint64 coordCount = 0; - for (int coordIdx = 0; coordIdx < 3; coordIdx++) - { - for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) + for (size_t k = 0; k < cellCountK; k++) { - size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; - - for (size_t k = 0; k < cellCountK; k++) + for (size_t j = 0; j < cellCountJ; j++) { - for (size_t j = 0; j < cellCountJ; j++) + for (size_t i = 0; i < cellCountI; i++) { - for (size_t i = 0; i < cellCountI; i++) - { - size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); - rigGrid->cellCornerVertices(localCellIdx, cornerVerts); + size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); + rigGrid->cellCornerVertices(localCellIdx, cornerVerts); - cellCornerValues[coordCount++] = cornerVerts[cornerIndexMapping][coordIdx]; - } + doubleValues[valueIndex++] = cornerVerts[cornerIndexMapping][coordIdx]; } } } - } - - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCornerValues.data(), byteCount); - } - double totalTimeMS = timer.time() * 1000.0; - QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); + CVF_ASSERT(valueIndex, cellCount); - server->errorMessageDialog()->showMessage(resultInfo); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); + } + } return true; } @@ -348,6 +324,10 @@ class RiaGetActiveCellCorners : public RiaSocketCommand size_t activeCellCount = actCellInfo->globalActiveCellCount(); size_t doubleValueCount = activeCellCount * 3 * 8; + socketStream << (quint64)activeCellCount; + quint64 byteCount = doubleValueCount * sizeof(double); + socketStream << byteCount; + // This structure is supposed to be received by Octave using a NDArray. The ordering of this loop is // defined by the ordering of the receiving NDArray // @@ -359,31 +339,32 @@ class RiaGetActiveCellCorners : public RiaSocketCommand // dv(1) = 8; // dv(2) = 3; - std::vector cellCornerValues(doubleValueCount); cvf::Vec3d cornerVerts[8]; - quint64 coordCount = 0; + size_t blockByteCount = activeCellCount * sizeof(double); + std::vector doubleValues(blockByteCount); + for (int coordIdx = 0; coordIdx < 3; coordIdx++) { for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) { size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; + quint64 valueIndex = 0; + for (size_t globalCellIdx = 0; globalCellIdx < mainGrid->cells().size(); globalCellIdx++) { if (!actCellInfo->isActive(globalCellIdx)) continue; mainGrid->cellCornerVertices(globalCellIdx, cornerVerts); - cellCornerValues[coordCount++] = cornerVerts[cornerIndexMapping][coordIdx]; + doubleValues[valueIndex++] = cornerVerts[cornerIndexMapping][coordIdx]; } - } - } - socketStream << (quint64)activeCellCount; - quint64 byteCount = doubleValueCount * sizeof(double); - socketStream << byteCount; + CVF_ASSERT(valueIndex == activeCellCount); - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)cellCornerValues.data(), byteCount); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); + } + } return true; } diff --git a/OctavePlugin/riGetActiveCellCenters.cpp b/OctavePlugin/riGetActiveCellCenters.cpp index 90c1631f30..a98ba06bac 100644 --- a/OctavePlugin/riGetActiveCellCenters.cpp +++ b/OctavePlugin/riGetActiveCellCenters.cpp @@ -1,7 +1,10 @@ #include +#include + #include #include "riSettings.h" +#include "riSocketTools.h" void getActiveCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 port, const qint32& caseId, const QString& porosityModel) @@ -61,24 +64,16 @@ void getActiveCellCenters(NDArray& cellCenterValues, const QString &hostName, qu cellCenterValues.resize(dv); - while (socket.bytesAvailable() < (qint64)(byteCount)) + double* internalMatrixData = cellCenterValues.fortran_vec(); + QStringList errorMessages; + if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) + for (int i = 0; i < errorMessages.size(); i++) { - error((("Waiting for data: ") + socket.errorString()).toLatin1().data()); - return; + error(errorMessages[i].toLatin1().data()); } - OCTAVE_QUIT; - } - - quint64 bytesRead = 0; - double* internalMatrixData = cellCenterValues.fortran_vec(); - bytesRead = socket.read((char*)(internalMatrixData), byteCount); - if (byteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - octave_stdout << "Active cell count: " << activeCellCount << std::endl; + OCTAVE_QUIT; } return; diff --git a/OctavePlugin/riGetActiveCellCorners.cpp b/OctavePlugin/riGetActiveCellCorners.cpp index 6fb285cc4a..47ffad52bc 100644 --- a/OctavePlugin/riGetActiveCellCorners.cpp +++ b/OctavePlugin/riGetActiveCellCorners.cpp @@ -1,7 +1,10 @@ #include +#include + #include #include "riSettings.h" +#include "riSocketTools.h" void getActiveCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 port, const qint32& caseId, const QString& porosityModel) @@ -61,24 +64,16 @@ void getActiveCellCorners(NDArray& cellCornerValues, const QString &hostName, qu dv(2) = 3; cellCornerValues.resize(dv); - while (socket.bytesAvailable() < (qint64)(byteCount)) + double* internalMatrixData = cellCornerValues.fortran_vec(); + QStringList errorMessages; + if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) + for (int i = 0; i < errorMessages.size(); i++) { - error((("Waiting for data: ") + socket.errorString()).toLatin1().data()); - return; + error(errorMessages[i].toLatin1().data()); } - OCTAVE_QUIT; - } - - quint64 bytesRead = 0; - double* internalMatrixData = cellCornerValues.fortran_vec(); - bytesRead = socket.read((char*)(internalMatrixData), byteCount); - if (byteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - octave_stdout << "Active cell count: " << activeCellCount << std::endl; + OCTAVE_QUIT; } return; diff --git a/OctavePlugin/riGetCellCenters.cpp b/OctavePlugin/riGetCellCenters.cpp index cb65de3d01..4f57d08a2b 100644 --- a/OctavePlugin/riGetCellCenters.cpp +++ b/OctavePlugin/riGetCellCenters.cpp @@ -1,7 +1,10 @@ #include +#include + #include #include "riSettings.h" +#include "riSocketTools.h" void getCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 port, const qint32& caseId, const quint32& gridIndex) @@ -66,39 +69,19 @@ void getCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 dv(3) = 3; cellCenterValues.resize(dv); - while (socket.bytesAvailable() < (qint64)(byteCount)) - { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) - { - error((("Waiting for data: ") + socket.errorString()).toLatin1().data()); - return; - } - OCTAVE_QUIT; - } - - //octave_stdout << " riGetCellCenters : I = " << cellCountI <<" J = " << cellCountJ << " K = " << cellCountK << std::endl; - //octave_stdout << " riGetCellCenters : numDoubles = " << valueCount << std::endl; double* internalMatrixData = cellCenterValues.fortran_vec(); - -#if 0 - octave_idx_type valueCount = cellCenterValues.length(); - double val; - for (octave_idx_type i = 0; i < valueCount; i++) + QStringList errorMessages; + if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) { - socketStream >> internalMatrixData[i]; - } -#else - quint64 bytesRead = 0; - bytesRead = socket.read((char*)(internalMatrixData), byteCount); + for (int i = 0; i < errorMessages.size(); i++) + { + error(errorMessages[i].toLatin1().data()); + } - if (byteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - octave_stdout << "Cell count: " << cellCount << std::endl; + OCTAVE_QUIT; } -#endif return; } diff --git a/OctavePlugin/riGetCellCorners.cpp b/OctavePlugin/riGetCellCorners.cpp index f5e3b2c356..2571371a76 100644 --- a/OctavePlugin/riGetCellCorners.cpp +++ b/OctavePlugin/riGetCellCorners.cpp @@ -84,41 +84,6 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 OCTAVE_QUIT; } - octave_stdout << "Bytes count processed : " << byteCount << std::endl; - - - /* - while (socket.bytesAvailable() < (qint64)(byteCount)) - { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) - { - error((("Waiting for data: ") + socket.errorString()).toLatin1().data()); - return; - } - OCTAVE_QUIT; - } - - double* internalMatrixData = cellCornerValues.fortran_vec(); - -#if 0 - double val; - for (octave_idx_type i = 0; i < valueCount; i++) - { - socketStream >> internalMatrixData[i]; - } -#else - quint64 bytesRead = 0; - bytesRead = socket.read((char*)(internalMatrixData), byteCount); - - if (byteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - octave_stdout << "Cell count: " << cellCount << std::endl; - } - -#endif - */ - return; } From 1693ae25dd7ec834979503767bde5344bdca68e2 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 3 Apr 2014 11:56:01 +0200 Subject: [PATCH 085/130] Updated riGetGridProperty --- .../RiaPropertyDataCommands.cpp | 57 +++--------- OctavePlugin/riGetGridProperty.cpp | 92 ++----------------- 2 files changed, 22 insertions(+), 127 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index 00210e4e21..87cf148f7c 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -306,60 +306,27 @@ class RiaGetGridProperty: public RiaSocketCommand quint64 timestepCount = (quint64)requestedTimesteps.size(); socketStream << timestepCount; - size_t valueIdx = 0; - cvf::Timer timer; - - if (RiaApplication::instance()->preferences()->useStreamTransfer()) + for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { - for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) + cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); + if (cellCenterDataAccessObject.isNull()) { - cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); - if (cellCenterDataAccessObject.isNull()) - { - continue; - } - - for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) - { - double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); - if (cellValue == HUGE_VAL) - { - cellValue = 0.0; - } - - socketStream << cellValue; - } + continue; } - } - else - { - for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) + std::vector values(rigGrid->cellCount()); + for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) { - cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); - if (cellCenterDataAccessObject.isNull()) - { - continue; - } - - std::vector values(rigGrid->cellCount()); - for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) + double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); + if (cellValue == HUGE_VAL) { - double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); - if (cellValue == HUGE_VAL) - { - cellValue = 0.0; - } - values[valueIdx++] = cellValue; + cellValue = 0.0; } - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), values.size() * sizeof(double)); + values[cellIdx] = cellValue; } - } - double totalTimeMS = timer.time() * 1000.0; - QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); - - server->errorMessageDialog()->showMessage(resultInfo); + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), values.size() * sizeof(double)); + } return true; } diff --git a/OctavePlugin/riGetGridProperty.cpp b/OctavePlugin/riGetGridProperty.cpp index 3b1fbc589f..e477cd767a 100644 --- a/OctavePlugin/riGetGridProperty.cpp +++ b/OctavePlugin/riGetGridProperty.cpp @@ -1,6 +1,11 @@ #include +#include + #include + #include "riSettings.h" +#include "riSocketTools.h" + void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 serverPort, const int& caseId, int gridIdx, QString propertyName, const int32NDArray& requestedTimeSteps, QString porosityModel) @@ -61,8 +66,6 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 totalByteCount = cellCountI*cellCountJ*cellCountK*timestepCount*sizeof(double); - qint64 timestepByteCount = cellCountI*cellCountJ*cellCountK*sizeof(double); - if (!(totalByteCount)) { error ("Could not find the requested data in ResInsight"); @@ -78,93 +81,18 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 propertyFrames.resize(dv); - -#if 1 - // Wait for available data for each timestep, then read data for each timestep - - qint64 totalBytesRead = 0; - - for (size_t tIdx = 0; tIdx < timestepCount; ++tIdx) + double* internalMatrixData = propertyFrames.fortran_vec(); + QStringList errorMessages; + if (!readBlockData(socket, (char*)(internalMatrixData), totalByteCount, errorMessages)) { - qint64 bytesAvailable = socket.bytesAvailable() ; - - while ( bytesAvailable < (qint64)timestepByteCount) + for (int i = 0; i < errorMessages.size(); i++) { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) - { - error((("Waiting for timestep data number: ") + QString::number(tIdx)+ ": " + socket.errorString()).toLatin1().data()); - octave_stdout << "Cellcount: " << cellCountI*cellCountJ*cellCountK << ", Timesteps: " << timestepCount << std::endl; - return ; - } - - bytesAvailable = socket.bytesAvailable(); - - OCTAVE_QUIT; + error(errorMessages[i].toLatin1().data()); } - qint64 bytesRead = 0; - double * internalMatrixData = propertyFrames.fortran_vec(); - - // Raw data transfer. Faster. Not possible when dealing with coarsening - bytesRead = socket.read(((char*)(internalMatrixData)) + tIdx * timestepByteCount, timestepByteCount); - - if ((qint64)timestepByteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - octave_stdout << "Cellcount: " << cellCountI*cellCountJ*cellCountK << ", Timesteps count: " << timestepCount << std::endl; - octave_stdout << "Timestep : " << tIdx << std::endl; - } - - totalBytesRead += bytesRead; - - OCTAVE_QUIT; - } - - if ((qint64)totalByteCount != totalBytesRead) - { - error("Could not read binary double data properly from socket"); - } - - #else - - // Wait for available data - qint64 bytesAvailable = socket.bytesAvailable() ; - - while (bytesAvailable < (qint64)totalByteCount) - { - octave_stdout << "Waiting for data. Has : " << bytesAvailable << " Needs :" << totalByteCount << std::endl; - if (!socket.waitForReadyRead(riOctavePlugin::shortTimeOutMilliSecs)) - { - //error(("Waiting for data : " + socket.errorString()).toLatin1().data()); - //return ; - } - - bytesAvailable = socket.bytesAvailable() ; OCTAVE_QUIT; } - qint64 bytesRead = 0; - double * internalMatrixData = propertyFrames.fortran_vec(); - -#if 0 - - char* dataBuffer = new char[totalByteCount]; - bytesRead = socket.read(dataBuffer, totalByteCount); - - -#else - - // Raw data transfer. Faster. - bytesRead = socket.read((char*)(internalMatrixData ), totalByteCount); -#endif - - - if ((qint64)totalByteCount != bytesRead) - { - error("Could not read binary double data properly from socket"); - } - -#endif QString tmp = QString("riGetGridProperty : Read %1").arg(propertyName); if (caseId < 0) From 32bfb65a9d197873b7a24a78d34acd5849e46f08 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 14 Apr 2014 14:36:47 +0200 Subject: [PATCH 086/130] Added socket data transfer Added one common class used to transfer data using socket. This class is used both from the Octave plugins and from the socket server code in ResInsight --- ApplicationCode/CMakeLists.txt | 3 + .../SocketInterface/RiaSocketDataTransfer.cpp | 102 ++++++++++++++++++ .../SocketInterface/RiaSocketDataTransfer.h | 36 +++++++ .../SocketInterface/RiaSocketTools.cpp | 84 +++------------ .../SocketInterface/RiaSocketTools.h | 1 - OctavePlugin/CMakeLists.txt | 6 +- 6 files changed, 156 insertions(+), 76 deletions(-) create mode 100644 ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp create mode 100644 ApplicationCode/SocketInterface/RiaSocketDataTransfer.h diff --git a/ApplicationCode/CMakeLists.txt b/ApplicationCode/CMakeLists.txt index 29c2db248b..d4e7e4113f 100644 --- a/ApplicationCode/CMakeLists.txt +++ b/ApplicationCode/CMakeLists.txt @@ -58,6 +58,7 @@ set( SOCKET_INTERFACE_FILES SocketInterface/RiaPropertyDataCommands.cpp SocketInterface/RiaWellDataCommands.cpp SocketInterface/RiaSocketTools.cpp + SocketInterface/RiaSocketDataTransfer.cpp ) @@ -153,6 +154,8 @@ list( REMOVE_ITEM RAW_SOURCES Application/RiaImageCompareReporter.cpp Application/RiaRegressionTest.cpp + SocketInterface/RiaSocketDataTransfer.cpp + FileInterface/RifEclipseInputFileTools.cpp FileInterface/RifEclipseOutputFileTools.cpp FileInterface/RifEclipseRestartFilesetAccess.cpp diff --git a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp new file mode 100644 index 0000000000..c49ff5fa1f --- /dev/null +++ b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp @@ -0,0 +1,102 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA, Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaSocketDataTransfer.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiaSocketDataTransfer::writeBlockDataToSocket(QTcpSocket* socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages) +{ + quint64 bytesWritten = 0; + int blockCount = 0; + + quint64 maxBlockSize = doubleValueCountInBlock() * sizeof(double); + + while (bytesWritten < bytesToWrite) + { + quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize); + + qint64 actuallyBytesWritten = socket->write(data + bytesWritten, byteCountToWrite); + if (actuallyBytesWritten < 0) + { + errorMessages.push_back("Error detected when writing data, error string from socket"); + errorMessages.push_back(socket->errorString()); + + return false; + } + + bytesWritten += actuallyBytesWritten; + + blockCount++; + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiaSocketDataTransfer::readBlockDataFromSocket(QTcpSocket* socket, char* data, quint64 bytesToRead, QStringList& errorMessages) +{ + quint64 bytesRead = 0; + int blockCount = 0; + + quint64 maxBlockSize = doubleValueCountInBlock() * sizeof(double); + + while (bytesRead < bytesToRead) + { + if (socket->bytesAvailable()) + { + quint64 byteCountToRead = qMin(bytesToRead - bytesRead, maxBlockSize); + + qint64 actuallyBytesRead = socket->read(data + bytesRead, byteCountToRead); + if (actuallyBytesRead < 0) + { + errorMessages.push_back("Error detected when reading data, error string from socket"); + errorMessages.push_back(socket->errorString()); + + return false; + } + + bytesRead += actuallyBytesRead; + blockCount++; + } + else + { + if (!socket->waitForReadyRead()) + { + errorMessages.push_back("Waited for data for %1 milli seconds."); + errorMessages.push_back(socket->errorString()); + + return false; + } + } + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RiaSocketDataTransfer::doubleValueCountInBlock() +{ + return 2000; +} + diff --git a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.h b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.h new file mode 100644 index 0000000000..06ae14b379 --- /dev/null +++ b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.h @@ -0,0 +1,36 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA, Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include +#include + +//================================================================================================== +/// Utility class used for transfer of data using QTcpSocket +/// +/// As the compile configuration for octave plugins is quite complex, +// the octave plugins includes the cpp-file to be able to compile only one file per plugin +//================================================================================================== +class RiaSocketDataTransfer +{ +public: + static size_t doubleValueCountInBlock(); + +public: + static bool writeBlockDataToSocket(QTcpSocket* socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages); + static bool readBlockDataFromSocket(QTcpSocket* socket, char* data, quint64 bytesToRead, QStringList& errorMessages); +}; diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.cpp b/ApplicationCode/SocketInterface/RiaSocketTools.cpp index 64cc8e0c11..86f7ce6086 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketTools.cpp @@ -38,8 +38,9 @@ #include "RimInputPropertyCollection.h" -#include +#include "RiaSocketDataTransfer.h" +#include //-------------------------------------------------------------------------------------------------- /// @@ -104,89 +105,28 @@ void RiaSocketTools::getCaseInfoFromCase(RimCase* rimCase, qint64& caseId, QStri } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- bool RiaSocketTools::writeBlockData(RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite) { cvf::Timer timer; - quint64 bytesWritten = 0; - int blockCount = 0; + QStringList errorMessages; + bool writeSucceded = RiaSocketDataTransfer::writeBlockDataToSocket(socket, data, bytesToWrite, errorMessages); - quint64 maxBlockSize = RiaApplication::instance()->preferences()->blockSize(); - - - while (bytesWritten < bytesToWrite) + if (server) { - quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize); - - qint64 actuallyBytesWritten = socket->write(data + bytesWritten, byteCountToWrite); - if (actuallyBytesWritten < 0) + for (int i = 0; i < errorMessages.size(); i++) { - if (server) - { - QString errorMessage = "Error detected when writing data, error string from socket : \n" + socket->errorString(); - - server->errorMessageDialog()->showMessage(errorMessage); - } - - return false; + server->errorMessageDialog()->showMessage(errorMessages[i]); } - bytesWritten += actuallyBytesWritten; - - blockCount++; - } - - if (server) - { double totalTimeMS = timer.time() * 1000.0; - QString resultInfo = QString("Total time '%1 ms'\nTotal bytes written . %2\nNumber of blocks : %3\nBlock size : %4").arg(totalTimeMS).arg(bytesWritten).arg(blockCount).arg(maxBlockSize); + QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); server->errorMessageDialog()->showMessage(resultInfo); } - return true; + return writeSucceded; } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RiaSocketTools::readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages) -{ - quint64 bytesRead = 0; - int blockCount = 0; - - quint64 maxBlockSize = RiaApplication::instance()->preferences()->blockSize(); - - while (bytesRead < bytesToRead) - { - if (socket.bytesAvailable()) - { - quint64 byteCountToRead = qMin(bytesToRead - bytesRead, maxBlockSize); - - qint64 actuallyBytesRead = socket.read(data + bytesRead, byteCountToRead); - if (actuallyBytesRead < 0) - { - errorMessages.push_back("Error detected when writing data, error string from socket"); - errorMessages.push_back(socket.errorString()); - - return false; - } - - bytesRead += actuallyBytesRead; - blockCount++; - } - else - { - if (!socket.waitForReadyRead()) - { - errorMessages.push_back("Waited for data for %1 milli seconds."); - errorMessages.push_back(socket.errorString()); - - return false; - } - } - } - - return true; -} - diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.h b/ApplicationCode/SocketInterface/RiaSocketTools.h index 5a24731237..b331799e2e 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.h +++ b/ApplicationCode/SocketInterface/RiaSocketTools.h @@ -28,5 +28,4 @@ class RiaSocketTools static void getCaseInfoFromCase(RimCase* rimCase, qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId); static bool writeBlockData(RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite); - static bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages); }; diff --git a/OctavePlugin/CMakeLists.txt b/OctavePlugin/CMakeLists.txt index 7a11e18ab9..80d714789f 100644 --- a/OctavePlugin/CMakeLists.txt +++ b/OctavePlugin/CMakeLists.txt @@ -88,7 +88,7 @@ if (RESINSIGHT_OCTAVE_PLUGIN_QMAKE AND RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE) OUTPUT "${octFileName}" COMMAND call "\"%VS100COMNTOOLS%../../VC/vcvarsall.bat\"" x86 COMMAND ${CMAKE_COMMAND} ARGS -E chdir ${RESINSIGHT_OCTAVE_BIN_DIR} ${RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE} -I${OCTAVE_QT_QTNETWORK_INCLUDE_DIR} - -I${OCTAVE_QT_QTCORE_INCLUDE_DIR} -I${OCTAVE_QT_INCLUDE_DIR} ${RPATH_COMMAND} + -I${OCTAVE_QT_QTCORE_INCLUDE_DIR} -I${OCTAVE_QT_INCLUDE_DIR} -I${ResInsight_SOURCE_DIR}/ApplicationCode/SocketInterface ${RPATH_COMMAND} -L${OCTAVE_QT_LIBRARY_DIR} -lQtCore${QT_LIBRARY_POSTFIX} -lQtNetwork${QT_LIBRARY_POSTFIX} -o "${octFileName}" "${srcFileName}" DEPENDS "${srcFileName}" COMMENT "===> 32-bit x86 VS2010 : Generating ${octFileName}" @@ -97,7 +97,7 @@ if (RESINSIGHT_OCTAVE_PLUGIN_QMAKE AND RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE) add_custom_command( OUTPUT "${octFileName}" COMMAND ${CMAKE_COMMAND} ARGS -E chdir ${RESINSIGHT_OCTAVE_BIN_DIR} ${RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE} -I${OCTAVE_QT_QTNETWORK_INCLUDE_DIR} - -I${OCTAVE_QT_QTCORE_INCLUDE_DIR} -I${OCTAVE_QT_INCLUDE_DIR} ${RPATH_COMMAND} + -I${OCTAVE_QT_QTCORE_INCLUDE_DIR} -I${OCTAVE_QT_INCLUDE_DIR} -I${ResInsight_SOURCE_DIR}/ApplicationCode/SocketInterface ${RPATH_COMMAND} -L${OCTAVE_QT_LIBRARY_DIR} -lQtCore${QT_LIBRARY_POSTFIX} -lQtNetwork${QT_LIBRARY_POSTFIX} -o "${octFileName}" "${srcFileName}" DEPENDS "${srcFileName}" COMMENT "===> Generating ${octFileName}" @@ -107,7 +107,7 @@ if (RESINSIGHT_OCTAVE_PLUGIN_QMAKE AND RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE) add_custom_command( OUTPUT "${octFileName}" COMMAND OCTAVE_HOME=${OCTAVE_HOME} ${RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE} - -I${OCTAVE_QT_QTNETWORK_INCLUDE_DIR} -I${OCTAVE_QT_QTCORE_INCLUDE_DIR} -I${OCTAVE_QT_INCLUDE_DIR} ${RPATH_COMMAND} + -I${OCTAVE_QT_QTNETWORK_INCLUDE_DIR} -I${OCTAVE_QT_QTCORE_INCLUDE_DIR} -I${OCTAVE_QT_INCLUDE_DIR} -I${ResInsight_SOURCE_DIR}/ApplicationCode/SocketInterface ${RPATH_COMMAND} -L${OCTAVE_QT_LIBRARY_DIR} -lQtCore -lQtNetwork -o "${octFileName}" "${srcFileName}" DEPENDS "${srcFileName}" COMMENT "===> Generating ${octFileName}" From eec2ffbecdd751087fb83de7f88f8528288f462d Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 15 Apr 2014 13:04:57 +0200 Subject: [PATCH 087/130] Fixed invalid assert --- ApplicationCode/SocketInterface/RiaGeometryCommands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp index 2ca72a655d..c76bc690ae 100644 --- a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp @@ -276,7 +276,7 @@ class RiaGetCellCorners : public RiaSocketCommand } } - CVF_ASSERT(valueIndex, cellCount); + CVF_ASSERT(valueIndex == cellCount); RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); } From 19b655542abda3ca6f83ca1ceb6de7212e5a9852 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 15 Apr 2014 13:40:53 +0200 Subject: [PATCH 088/130] Use block transfer for data transfer of cell properties --- .../RiaPropertyDataCommands.cpp | 98 ++++++++++++------- .../SocketInterface/RiaSocketDataTransfer.cpp | 13 ++- .../SocketInterface/RiaSocketTools.cpp | 8 +- OctavePlugin/CMakeLists.txt | 36 +++---- OctavePlugin/riGetActiveCellProperty.cpp | 45 +++------ OctavePlugin/riGetGridProperty.cpp | 6 +- OctavePlugin/riSetActiveCellProperty.cpp | 32 +++--- OctavePlugin/riSetGridProperty.cpp | 52 +++++----- OctavePlugin/riSocketTools.h | 4 +- 9 files changed, 154 insertions(+), 140 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index 87cf148f7c..385ee7603d 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -42,6 +42,7 @@ #include #include "RiaApplication.h" #include "RiaPreferences.h" +#include "RiaSocketDataTransfer.h" //-------------------------------------------------------------------------------------------------- @@ -145,6 +146,9 @@ class RiaGetActiveCellProperty: public RiaSocketCommand socketStream << timestepByteCount ; // Then write the data. + size_t valueCount = RiaSocketDataTransfer::doubleValueCountInBlock(); + std::vector values(valueCount); + size_t valueIndex = 0; size_t globalCellCount = activeInfo->globalCellCount(); for (size_t tIdx = 0; tIdx < requestedTimesteps.size(); ++tIdx) @@ -156,37 +160,34 @@ class RiaGetActiveCellProperty: public RiaSocketCommand { if (resultIdx < scalarResultFrames->at(requestedTimesteps[tIdx]).size()) { - socketStream << scalarResultFrames->at(requestedTimesteps[tIdx])[resultIdx]; + values[valueIndex] = scalarResultFrames->at(requestedTimesteps[tIdx])[resultIdx]; } else { - socketStream << HUGE_VAL; + values[valueIndex] = HUGE_VAL; + } + + valueIndex++; + if (valueIndex >= valueCount) + { + if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double))) + { + return false; + } + + valueIndex = 0; } } } } -#if 0 - // This aproach is faster but does not handle coarsening - size_t timestepResultCount = scalarResultFrames->front().size(); - quint64 timestepByteCount = (quint64)(timestepResultCount*sizeof(double)); - socketStream << timestepByteCount ; - - // Then write the data. - for (size_t tIdx = 0; tIdx < requestedTimesteps.size(); ++tIdx) + // Write remaining data + if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double))) { -#if 1 // Write data as raw bytes, fast but does not handle byteswapping - server->currentClient()->write((const char *)scalarResultFrames->at(requestedTimesteps[tIdx]).data(), timestepByteCount); // Raw print of data. Fast but no platform conversion -#else // Write data using QDataStream, does byteswapping for us. Must use QDataStream on client as well - for (size_t cIdx = 0; cIdx < scalarResultFrames->at(requestedTimesteps[tIdx]).size(); ++cIdx) - { - socketStream << scalarResultFrames->at(tIdx)[cIdx]; - } -#endif + return false; } -#endif - } + } return true; } }; @@ -314,7 +315,9 @@ class RiaGetGridProperty: public RiaSocketCommand continue; } - std::vector values(rigGrid->cellCount()); + size_t valueCount = RiaSocketDataTransfer::doubleValueCountInBlock(); + std::vector values(valueCount); + size_t valueIndex = 0; for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) { double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); @@ -322,10 +325,24 @@ class RiaGetGridProperty: public RiaSocketCommand { cellValue = 0.0; } - values[cellIdx] = cellValue; + values[valueIndex++] = cellValue; + + if (valueIndex >= valueCount) + { + if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double))) + { + return false; + } + + valueIndex = 0; + } } - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), values.size() * sizeof(double)); + // Write remaining data + if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double))) + { + return false; + } } return true; @@ -552,16 +569,18 @@ class RiaSetActiveCellProperty: public RiaSocketCommand internalMatrixData = m_scalarResultsToAdd->at(m_requestedTimesteps[m_currentTimeStepNumberToRead]).data(); } -#if 1 // Use raw data transfer. Faster. - bytesRead = currentClient->read((char*)(internalMatrixData), m_bytesPerTimeStepToRead); -#else - for (size_t cIdx = 0; cIdx < cellCountFromOctave; ++cIdx) + QStringList errorMessages; + if (!RiaSocketDataTransfer::readBlockDataFromSocket(currentClient, (char*)(internalMatrixData), m_bytesPerTimeStepToRead, errorMessages)) { - socketStream >> internalMatrixData[cIdx]; + for (int i = 0; i < errorMessages.size(); i++) + { + server->errorMessageDialog()->showMessage(errorMessages[i]); + } - if (socketStream.status() == QDataStream::Ok) bytesRead += sizeof(double); + currentClient->abort(); + return true; } -#endif + // Map data from active to result index based container ( Coarsening is active) if (isCoarseningActive) { @@ -576,12 +595,6 @@ class RiaSetActiveCellProperty: public RiaSocketCommand } } - if ((int)m_bytesPerTimeStepToRead != bytesRead) - { - server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + - RiaSocketServer::tr("Could not read binary double data properly from socket")); - } - ++m_currentTimeStepNumberToRead; } @@ -896,8 +909,17 @@ class RiaSetGridProperty : public RiaSocketCommand std::vector doubleValues(cellCountFromOctave); - qint64 bytesRead = currentClient->read((char*)(doubleValues.data()), m_bytesPerTimeStepToRead); - size_t doubleValueIndex = 0; + QStringList errorMessages; + if (!RiaSocketDataTransfer::readBlockDataFromSocket(currentClient, (char*)(doubleValues.data()), m_bytesPerTimeStepToRead, errorMessages)) + { + for (int i = 0; i < errorMessages.size(); i++) + { + server->errorMessageDialog()->showMessage(errorMessages[i]); + } + + currentClient->abort(); + return true; + } cvf::ref cellCenterDataAccessObject = m_currentReservoir->reservoirData()->dataAccessObject(grid, m_porosityModelEnum, m_requestedTimesteps[m_currentTimeStepNumberToRead], m_currentScalarIndex); diff --git a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp index c49ff5fa1f..8671f2e28d 100644 --- a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp @@ -18,6 +18,7 @@ #include "RiaSocketDataTransfer.h" + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -55,15 +56,12 @@ bool RiaSocketDataTransfer::writeBlockDataToSocket(QTcpSocket* socket, const cha bool RiaSocketDataTransfer::readBlockDataFromSocket(QTcpSocket* socket, char* data, quint64 bytesToRead, QStringList& errorMessages) { quint64 bytesRead = 0; - int blockCount = 0; - - quint64 maxBlockSize = doubleValueCountInBlock() * sizeof(double); while (bytesRead < bytesToRead) { if (socket->bytesAvailable()) { - quint64 byteCountToRead = qMin(bytesToRead - bytesRead, maxBlockSize); + quint64 byteCountToRead = bytesToRead - bytesRead; qint64 actuallyBytesRead = socket->read(data + bytesRead, byteCountToRead); if (actuallyBytesRead < 0) @@ -75,7 +73,6 @@ bool RiaSocketDataTransfer::readBlockDataFromSocket(QTcpSocket* socket, char* da } bytesRead += actuallyBytesRead; - blockCount++; } else { @@ -87,6 +84,12 @@ bool RiaSocketDataTransfer::readBlockDataFromSocket(QTcpSocket* socket, char* da return false; } } + +// Allow Octave process to end a long running Octave function +#ifdef octave_oct_h + OCTAVE_QUIT; +#endif + } return true; diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.cpp b/ApplicationCode/SocketInterface/RiaSocketTools.cpp index 86f7ce6086..967c0b43b4 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketTools.cpp @@ -122,10 +122,10 @@ bool RiaSocketTools::writeBlockData(RiaSocketServer* server, QTcpSocket* socket, server->errorMessageDialog()->showMessage(errorMessages[i]); } - double totalTimeMS = timer.time() * 1000.0; - QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); - - server->errorMessageDialog()->showMessage(resultInfo); +// double totalTimeMS = timer.time() * 1000.0; +// QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS); +// +// server->errorMessageDialog()->showMessage(resultInfo); } return writeSucceded; diff --git a/OctavePlugin/CMakeLists.txt b/OctavePlugin/CMakeLists.txt index 80d714789f..a49a9e21d0 100644 --- a/OctavePlugin/CMakeLists.txt +++ b/OctavePlugin/CMakeLists.txt @@ -6,26 +6,26 @@ set(CPP_SOURCES riGetActiveCellProperty.cpp riSetActiveCellProperty.cpp - riGetActiveCellInfo.cpp - riGetMainGridDimensions.cpp - riGetCurrentCase.cpp - riGetCaseGroups.cpp - riGetSelectedCases.cpp - riGetCases.cpp - riGetTimeStepDates.cpp - riGetTimeStepDays.cpp - riGetGridDimensions.cpp - riGetCoarseningInfo.cpp - riGetCellCenters.cpp - riGetActiveCellCenters.cpp - riGetCellCorners.cpp - riGetActiveCellCorners.cpp +# riGetActiveCellInfo.cpp +# riGetMainGridDimensions.cpp +# riGetCurrentCase.cpp +# riGetCaseGroups.cpp +# riGetSelectedCases.cpp +# riGetCases.cpp +# riGetTimeStepDates.cpp +# riGetTimeStepDays.cpp +# riGetGridDimensions.cpp +# riGetCoarseningInfo.cpp +# riGetCellCenters.cpp +# riGetActiveCellCenters.cpp +# riGetCellCorners.cpp +# riGetActiveCellCorners.cpp riGetGridProperty.cpp riSetGridProperty.cpp - riGetPropertyNames.cpp - riGetWellNames.cpp - riGetWellStatus.cpp - riGetWellCells.cpp +# riGetPropertyNames.cpp +# riGetWellNames.cpp +# riGetWellStatus.cpp +# riGetWellCells.cpp ) if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") diff --git a/OctavePlugin/riGetActiveCellProperty.cpp b/OctavePlugin/riGetActiveCellProperty.cpp index 81b966f7d0..573e324f12 100644 --- a/OctavePlugin/riGetActiveCellProperty.cpp +++ b/OctavePlugin/riGetActiveCellProperty.cpp @@ -1,7 +1,12 @@ #include +#include + #include + #include "riSettings.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration + void getActiveCellProperty(Matrix& propertyFrames, const QString &serverName, quint16 serverPort, const qint64& caseId, QString propertyName, const int32NDArray& requestedTimeSteps, QString porosityModel) { @@ -63,44 +68,18 @@ void getActiveCellProperty(Matrix& propertyFrames, const QString &serverName, qu return; } - // Wait for available data for each timestep, then read data for each timestep + quint64 totalByteCount = byteCount * timestepCount; - for (size_t tIdx = 0; tIdx < timestepCount; ++tIdx) + double* internalMatrixData = propertyFrames.fortran_vec(); + QStringList errorMessages; + if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), totalByteCount, errorMessages)) { - while (socket.bytesAvailable() < (qint64)byteCount) - { - if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs)) - { - error((("Waiting for timestep data number: ") + QString::number(tIdx)+ ": " + socket.errorString()).toLatin1().data()); - octave_stdout << "Active cells: " << activeCellCount << ", Timesteps: " << timestepCount << std::endl; - return ; - } - OCTAVE_QUIT; - } - - qint64 bytesRead = 0; - double * internalMatrixData = propertyFrames.fortran_vec(); - -#if 0 - // Raw data transfer. Faster. Not possible when dealing with coarsening - // bytesRead = socket.read((char*)(internalMatrixData + tIdx * activeCellCount), byteCount); -#else - // Compatible transfer. Now the only one working - for (size_t cIdx = 0; cIdx < activeCellCount; ++cIdx) - { - socketStream >> internalMatrixData[tIdx * activeCellCount + cIdx]; - - if (socketStream.status() == QDataStream::Ok) bytesRead += sizeof(double); - } -#endif - - if ((qint64)byteCount != bytesRead) + for (int i = 0; i < errorMessages.size(); i++) { - error("Could not read binary double data properly from socket"); - octave_stdout << "Active cells: " << activeCellCount << ", Timesteps: " << timestepCount << std::endl; + error(errorMessages[i].toLatin1().data()); } - OCTAVE_QUIT; + return; } QString tmp = QString("riGetActiveCellProperty : Read %1").arg(propertyName); diff --git a/OctavePlugin/riGetGridProperty.cpp b/OctavePlugin/riGetGridProperty.cpp index e477cd767a..075c36ee48 100644 --- a/OctavePlugin/riGetGridProperty.cpp +++ b/OctavePlugin/riGetGridProperty.cpp @@ -4,7 +4,7 @@ #include #include "riSettings.h" -#include "riSocketTools.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 serverPort, @@ -83,14 +83,14 @@ void getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 double* internalMatrixData = propertyFrames.fortran_vec(); QStringList errorMessages; - if (!readBlockData(socket, (char*)(internalMatrixData), totalByteCount, errorMessages)) + if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), totalByteCount, errorMessages)) { for (int i = 0; i < errorMessages.size(); i++) { error(errorMessages[i].toLatin1().data()); } - OCTAVE_QUIT; + return; } QString tmp = QString("riGetGridProperty : Read %1").arg(propertyName); diff --git a/OctavePlugin/riSetActiveCellProperty.cpp b/OctavePlugin/riSetActiveCellProperty.cpp index 4953f25778..b4981a70cc 100644 --- a/OctavePlugin/riSetActiveCellProperty.cpp +++ b/OctavePlugin/riSetActiveCellProperty.cpp @@ -1,6 +1,10 @@ #include +#include + #include + #include "riSettings.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration void setEclipseProperty(const Matrix& propertyFrames, const QString &hostName, quint16 port, @@ -47,27 +51,29 @@ void setEclipseProperty(const Matrix& propertyFrames, const QString &hostName, q socketStream << (qint64)timeStepByteCount; const double* internalData = propertyFrames.fortran_vec(); - qint64 dataWritten = socket.write((const char *)internalData, timeStepByteCount*timeStepCount); - if (dataWritten == timeStepByteCount*timeStepCount) + QStringList errorMessages; + if (!RiaSocketDataTransfer::writeBlockDataToSocket(&socket, (const char *)internalData, timeStepByteCount*timeStepCount, errorMessages)) { - QString tmp = QString("riSetActiveCellProperty : Wrote %1").arg(propertyName); - - if (caseId == -1) + for (int i = 0; i < errorMessages.size(); i++) { - tmp += QString(" to current case."); + octave_stdout << errorMessages[i].toStdString(); } - else - { - tmp += QString(" to case with Id = %1.").arg(caseId); - } - octave_stdout << tmp.toStdString() << " Active Cells : " << cellCount << " Time steps : " << timeStepCount << std::endl; + + return; + } + + QString tmp = QString("riSetActiveCellProperty : Wrote %1").arg(propertyName); + + if (caseId == -1) + { + tmp += QString(" to current case."); } else { - error("riSetActiveCellProperty : Was not able to write the proper amount of data to ResInsight:"); - octave_stdout << " Active Cells : " << cellCount << "Time steps : " << timeStepCount << " Data Written: " << dataWritten << " Should have written: " << timeStepCount * cellCount * sizeof(double) << std::endl; + tmp += QString(" to case with Id = %1.").arg(caseId); } + octave_stdout << tmp.toStdString() << " Active Cells : " << cellCount << " Time steps : " << timeStepCount << std::endl; while(socket.bytesToWrite() && socket.state() == QAbstractSocket::ConnectedState) { diff --git a/OctavePlugin/riSetGridProperty.cpp b/OctavePlugin/riSetGridProperty.cpp index f5afe0a0f7..8598d4b32e 100644 --- a/OctavePlugin/riSetGridProperty.cpp +++ b/OctavePlugin/riSetGridProperty.cpp @@ -1,6 +1,10 @@ #include +#include + #include + #include "riSettings.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration void setEclipseProperty(const NDArray& propertyFrames, const QString &hostName, quint16 port, @@ -64,41 +68,41 @@ void setEclipseProperty(const NDArray& propertyFrames, const QString &hostName, socketStream << (qint64)singleTimeStepByteCount; const double* internalData = propertyFrames.fortran_vec(); - qint64 dataWritten = 0; - - for (size_t tsIdx = 0; tsIdx < timeStepCount; ++tsIdx) - { - dataWritten += socket.write(((const char *)internalData) + tsIdx*singleTimeStepByteCount, singleTimeStepByteCount); - } - - if (dataWritten == singleTimeStepByteCount*timeStepCount) - { - QString tmp = QString("riSetGridProperty : Wrote %1").arg(propertyName); - if (caseId == -1) - { - tmp += QString(" to current case,"); - } - else + QStringList errorMessages; + if (!RiaSocketDataTransfer::writeBlockDataToSocket(&socket, (const char *)internalData, timeStepCount*singleTimeStepByteCount, errorMessages)) + { + for (int i = 0; i < errorMessages.size(); i++) { - tmp += QString(" to case with Id = %1,").arg(caseId); + octave_stdout << errorMessages[i].toStdString(); } - - tmp += QString(" grid index: %1, ").arg(gridIndex); - octave_stdout << tmp.toStdString() << " Time steps : " << timeStepCount << std::endl; + size_t cellCount = cellCountI * cellCountJ * cellCountK; + error("riSetGridProperty : Was not able to write the proper amount of data to ResInsight:"); + octave_stdout << " Cell count : " << cellCount << "Time steps : " << timeStepCount << std::endl; + + return; + } + + QString tmp = QString("riSetGridProperty : Wrote %1").arg(propertyName); + + if (caseId == -1) + { + tmp += QString(" to current case,"); } else { - size_t cellCount = cellCountI * cellCountJ * cellCountK; - error("riSetGridProperty : Was not able to write the proper amount of data to ResInsight:"); - octave_stdout << " Cell count : " << cellCount << "Time steps : " << timeStepCount << " Data Written: " << dataWritten << " Should have written: " << timeStepCount * cellCount * sizeof(double) << std::endl; + tmp += QString(" to case with Id = %1,").arg(caseId); } + + tmp += QString(" grid index: %1, ").arg(gridIndex); + + octave_stdout << tmp.toStdString() << " Time steps : " << timeStepCount << std::endl; while(socket.bytesToWrite() && socket.state() == QAbstractSocket::ConnectedState) { - octave_stdout << "Bytes to write: " << socket.bytesToWrite() << std::endl << std::flush; - socket.waitForBytesWritten(2000); +// octave_stdout << "Bytes to write: " << socket.bytesToWrite() << std::endl << std::flush; + socket.waitForBytesWritten(riOctavePlugin::longTimeOutMilliSecs); OCTAVE_QUIT; } diff --git a/OctavePlugin/riSocketTools.h b/OctavePlugin/riSocketTools.h index 63cc24d890..f142313c4f 100644 --- a/OctavePlugin/riSocketTools.h +++ b/OctavePlugin/riSocketTools.h @@ -2,7 +2,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages) +bool readBlockData_to_be_deleted(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages) { quint64 bytesRead = 0; int blockCount = 0; @@ -51,7 +51,7 @@ bool readBlockData(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringL //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool writeBlockData(QTcpSocket& socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages) +bool writeBlockData_to_be_deleted(QTcpSocket& socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages) { quint64 bytesWritten = 0; int blockCount = 0; From e799a25c2eabd2355bfb46c179d95739463e5177 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 15 Apr 2014 14:03:41 +0200 Subject: [PATCH 089/130] Block transfer for active cell info --- .../SocketInterface/RiaCaseInfoCommands.cpp | 15 ++------------- OctavePlugin/riGetActiveCellInfo.cpp | 6 ++---- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp index e6444f314d..2426f95252 100644 --- a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp @@ -132,20 +132,9 @@ class RiaGetActiveCellInfo: public RiaSocketCommand quint64 timestepByteCount = (quint64)(timestepResultCount*sizeof(qint32)); socketStream << timestepByteCount; - // Then write the data. - for (size_t tIdx = 0; tIdx < columnCount; ++tIdx) - { -#if 1 // Write data as raw bytes, fast but does not handle byteswapping - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)activeCellInfo[tIdx].data(), timestepByteCount); - -#else // Write data using QDataStream, does byteswapping for us. Must use QDataStream on client as well - for (size_t cIdx = 0; cIdx < activeCellInfo[tIdx].size(); ++cIdx) - { - socketStream << activeCellInfo[tIdx][cIdx]; - } -#endif - } + // Write data as raw bytes, fast but does not handle byteswapping + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)activeCellInfo.data(), columnCount*timestepByteCount); return true; } diff --git a/OctavePlugin/riGetActiveCellInfo.cpp b/OctavePlugin/riGetActiveCellInfo.cpp index a7213a3697..8a9f4bc8eb 100644 --- a/OctavePlugin/riGetActiveCellInfo.cpp +++ b/OctavePlugin/riGetActiveCellInfo.cpp @@ -2,10 +2,8 @@ #include #include - #include "riSettings.h" -#include "riSocketTools.h" - +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration void getActiveCellInfo(int32NDArray& activeCellInfo, const QString &hostName, quint16 port, const qint64& caseId, const QString& porosityModel) { @@ -67,7 +65,7 @@ void getActiveCellInfo(int32NDArray& activeCellInfo, const QString &hostName, qu qint32* internalMatrixData = (qint32*)activeCellInfo.fortran_vec()->mex_get_data(); QStringList errorMessages; - if (!readBlockData(socket, (char*)(internalMatrixData), columnCount * byteCountForOneTimestep, errorMessages)) + if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), columnCount * byteCountForOneTimestep, errorMessages)) { for (int i = 0; i < errorMessages.size(); i++) { From f1a0bd679c06589d2fa13a868f27b3b8eb8242ff Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 15 Apr 2014 14:16:35 +0200 Subject: [PATCH 090/130] Removed riSocketTools and updated use of block data transfer --- OctavePlugin/CMakeLists.txt | 45 +++++++------- OctavePlugin/riGetActiveCellCenters.cpp | 5 +- OctavePlugin/riGetActiveCellCorners.cpp | 4 +- OctavePlugin/riGetCellCenters.cpp | 5 +- OctavePlugin/riGetCellCorners.cpp | 4 +- OctavePlugin/riGetCurrentCase.cpp | 1 - OctavePlugin/riSocketTools.h | 80 ------------------------- 7 files changed, 31 insertions(+), 113 deletions(-) delete mode 100644 OctavePlugin/riSocketTools.h diff --git a/OctavePlugin/CMakeLists.txt b/OctavePlugin/CMakeLists.txt index a49a9e21d0..4ee4dcc138 100644 --- a/OctavePlugin/CMakeLists.txt +++ b/OctavePlugin/CMakeLists.txt @@ -4,28 +4,28 @@ # See http://www.cmake.org/Wiki/CMakeUserFindOctave set(CPP_SOURCES - riGetActiveCellProperty.cpp - riSetActiveCellProperty.cpp -# riGetActiveCellInfo.cpp -# riGetMainGridDimensions.cpp -# riGetCurrentCase.cpp -# riGetCaseGroups.cpp -# riGetSelectedCases.cpp -# riGetCases.cpp -# riGetTimeStepDates.cpp -# riGetTimeStepDays.cpp -# riGetGridDimensions.cpp -# riGetCoarseningInfo.cpp -# riGetCellCenters.cpp -# riGetActiveCellCenters.cpp -# riGetCellCorners.cpp -# riGetActiveCellCorners.cpp - riGetGridProperty.cpp - riSetGridProperty.cpp -# riGetPropertyNames.cpp -# riGetWellNames.cpp -# riGetWellStatus.cpp -# riGetWellCells.cpp + riGetActiveCellProperty.cpp + riSetActiveCellProperty.cpp + riGetActiveCellInfo.cpp + riGetMainGridDimensions.cpp + riGetCurrentCase.cpp + riGetCaseGroups.cpp + riGetSelectedCases.cpp + riGetCases.cpp + riGetTimeStepDates.cpp + riGetTimeStepDays.cpp + riGetGridDimensions.cpp + riGetCoarseningInfo.cpp + riGetCellCenters.cpp + riGetActiveCellCenters.cpp + riGetCellCorners.cpp + riGetActiveCellCorners.cpp + riGetGridProperty.cpp + riSetGridProperty.cpp + riGetPropertyNames.cpp + riGetWellNames.cpp + riGetWellStatus.cpp + riGetWellCells.cpp ) if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") @@ -143,7 +143,6 @@ if (RESINSIGHT_OCTAVE_PLUGIN_QMAKE AND RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE) "${CMAKE_CURRENT_BINARY_DIR}/riGetWellCells.oct" SOURCES ${CPP_SOURCES} - riSocketTools.h riSettings.h ) diff --git a/OctavePlugin/riGetActiveCellCenters.cpp b/OctavePlugin/riGetActiveCellCenters.cpp index a98ba06bac..862172ba0a 100644 --- a/OctavePlugin/riGetActiveCellCenters.cpp +++ b/OctavePlugin/riGetActiveCellCenters.cpp @@ -4,7 +4,7 @@ #include #include "riSettings.h" -#include "riSocketTools.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration void getActiveCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 port, const qint32& caseId, const QString& porosityModel) @@ -66,7 +66,8 @@ void getActiveCellCenters(NDArray& cellCenterValues, const QString &hostName, qu double* internalMatrixData = cellCenterValues.fortran_vec(); QStringList errorMessages; - if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) + + if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), byteCount, errorMessages)) { for (int i = 0; i < errorMessages.size(); i++) { diff --git a/OctavePlugin/riGetActiveCellCorners.cpp b/OctavePlugin/riGetActiveCellCorners.cpp index 47ffad52bc..d018310285 100644 --- a/OctavePlugin/riGetActiveCellCorners.cpp +++ b/OctavePlugin/riGetActiveCellCorners.cpp @@ -4,7 +4,7 @@ #include #include "riSettings.h" -#include "riSocketTools.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration void getActiveCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 port, const qint32& caseId, const QString& porosityModel) @@ -66,7 +66,7 @@ void getActiveCellCorners(NDArray& cellCornerValues, const QString &hostName, qu double* internalMatrixData = cellCornerValues.fortran_vec(); QStringList errorMessages; - if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) + if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), byteCount, errorMessages)) { for (int i = 0; i < errorMessages.size(); i++) { diff --git a/OctavePlugin/riGetCellCenters.cpp b/OctavePlugin/riGetCellCenters.cpp index 4f57d08a2b..a8255b6fb5 100644 --- a/OctavePlugin/riGetCellCenters.cpp +++ b/OctavePlugin/riGetCellCenters.cpp @@ -4,7 +4,7 @@ #include #include "riSettings.h" -#include "riSocketTools.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration void getCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 port, const qint32& caseId, const quint32& gridIndex) @@ -69,10 +69,9 @@ void getCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 dv(3) = 3; cellCenterValues.resize(dv); - double* internalMatrixData = cellCenterValues.fortran_vec(); QStringList errorMessages; - if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) + if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), byteCount, errorMessages)) { for (int i = 0; i < errorMessages.size(); i++) { diff --git a/OctavePlugin/riGetCellCorners.cpp b/OctavePlugin/riGetCellCorners.cpp index 2571371a76..2ed5d264b9 100644 --- a/OctavePlugin/riGetCellCorners.cpp +++ b/OctavePlugin/riGetCellCorners.cpp @@ -4,7 +4,7 @@ #include #include "riSettings.h" -#include "riSocketTools.h" +#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration @@ -74,7 +74,7 @@ void getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 double* internalMatrixData = cellCornerValues.fortran_vec(); QStringList errorMessages; - if (!readBlockData(socket, (char*)(internalMatrixData), byteCount, errorMessages)) + if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), byteCount, errorMessages)) { for (int i = 0; i < errorMessages.size(); i++) { diff --git a/OctavePlugin/riGetCurrentCase.cpp b/OctavePlugin/riGetCurrentCase.cpp index 88cc38088d..80b0ffe4ac 100644 --- a/OctavePlugin/riGetCurrentCase.cpp +++ b/OctavePlugin/riGetCurrentCase.cpp @@ -3,7 +3,6 @@ #include #include "riSettings.h" -#include "riSocketTools.h" void getCurrentCase(qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId, const QString &hostName, quint16 port) { diff --git a/OctavePlugin/riSocketTools.h b/OctavePlugin/riSocketTools.h deleted file mode 100644 index f142313c4f..0000000000 --- a/OctavePlugin/riSocketTools.h +++ /dev/null @@ -1,80 +0,0 @@ - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool readBlockData_to_be_deleted(QTcpSocket& socket, char* data, quint64 bytesToRead, QStringList& errorMessages) -{ - quint64 bytesRead = 0; - int blockCount = 0; - - quint64 maxBlockSize = riOctavePlugin::socketMaxByteCount; - - while (bytesRead < bytesToRead) - { - if (socket.bytesAvailable()) - { - quint64 byteCountToRead = qMin(bytesToRead - bytesRead, maxBlockSize); - - qint64 actuallyBytesRead = socket.read(data + bytesRead, byteCountToRead); - if (actuallyBytesRead < 0) - { - errorMessages.push_back("Error detected when reading data, error string from socket :"); - errorMessages.push_back(socket.errorString()); - - return false; - } - - bytesRead += actuallyBytesRead; - - octave_stdout << "Bytes read " << bytesRead << " of total " << bytesToRead << std::endl; - - blockCount++; - } - else - { - if (!socket.waitForReadyRead()) - { - errorMessages.push_back("Waited for data for %1 milli seconds."); - errorMessages.push_back(socket.errorString()); - - return false; - } - } - } - - octave_stdout << "Bytes read " << bytesToRead << std::endl; - - return true; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool writeBlockData_to_be_deleted(QTcpSocket& socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages) -{ - quint64 bytesWritten = 0; - int blockCount = 0; - - quint64 maxBlockSize = riOctavePlugin::socketMaxByteCount; - - while (bytesWritten < bytesToWrite) - { - quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize); - - qint64 actuallyBytesWritten = socket.write(data + bytesWritten, byteCountToWrite); - if (actuallyBytesWritten < 0) - { - errorMessages.push_back("Error detected when writing data, error string from socket"); - errorMessages.push_back(socket.errorString()); - - return false; - } - - bytesWritten += actuallyBytesWritten; - - blockCount++; - } - - return true; -} From d529e58c56d57863d6069992b23a83d744a6f843 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 15 Apr 2014 16:20:21 +0200 Subject: [PATCH 091/130] Fixed block transfer --- ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp index 2426f95252..e81b9db3ea 100644 --- a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp @@ -132,9 +132,10 @@ class RiaGetActiveCellInfo: public RiaSocketCommand quint64 timestepByteCount = (quint64)(timestepResultCount*sizeof(qint32)); socketStream << timestepByteCount; - - // Write data as raw bytes, fast but does not handle byteswapping - RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)activeCellInfo.data(), columnCount*timestepByteCount); + for (size_t tIdx = 0; tIdx < columnCount; ++tIdx) + { + RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)activeCellInfo[tIdx].data(), timestepByteCount); + } return true; } From 0f8b8448735008d0d7314a13d11ad0213b088972 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 24 Apr 2014 07:40:29 +0200 Subject: [PATCH 092/130] Use max block size when reading from socket --- .../SocketInterface/RiaPropertyDataCommands.cpp | 4 ++-- .../SocketInterface/RiaSocketDataTransfer.cpp | 16 ++++++++++++---- .../SocketInterface/RiaSocketDataTransfer.h | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index 385ee7603d..1d1b1b5420 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -146,7 +146,7 @@ class RiaGetActiveCellProperty: public RiaSocketCommand socketStream << timestepByteCount ; // Then write the data. - size_t valueCount = RiaSocketDataTransfer::doubleValueCountInBlock(); + size_t valueCount = RiaSocketDataTransfer::maximumValueCountInBlock(); std::vector values(valueCount); size_t valueIndex = 0; @@ -315,7 +315,7 @@ class RiaGetGridProperty: public RiaSocketCommand continue; } - size_t valueCount = RiaSocketDataTransfer::doubleValueCountInBlock(); + size_t valueCount = RiaSocketDataTransfer::maximumValueCountInBlock(); std::vector values(valueCount); size_t valueIndex = 0; for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) diff --git a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp index 8671f2e28d..0d2ec8879f 100644 --- a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp @@ -27,7 +27,7 @@ bool RiaSocketDataTransfer::writeBlockDataToSocket(QTcpSocket* socket, const cha quint64 bytesWritten = 0; int blockCount = 0; - quint64 maxBlockSize = doubleValueCountInBlock() * sizeof(double); + quint64 maxBlockSize = maximumValueCountInBlock() * sizeof(double); while (bytesWritten < bytesToWrite) { @@ -57,11 +57,14 @@ bool RiaSocketDataTransfer::readBlockDataFromSocket(QTcpSocket* socket, char* da { quint64 bytesRead = 0; + quint64 maxBlockSize = maximumValueCountInBlock() * sizeof(double); + while (bytesRead < bytesToRead) { if (socket->bytesAvailable()) { quint64 byteCountToRead = bytesToRead - bytesRead; + byteCountToRead = qMin(byteCountToRead, maxBlockSize); qint64 actuallyBytesRead = socket->read(data + bytesRead, byteCountToRead); if (actuallyBytesRead < 0) @@ -73,6 +76,10 @@ bool RiaSocketDataTransfer::readBlockDataFromSocket(QTcpSocket* socket, char* da } bytesRead += actuallyBytesRead; + +#ifdef octave_oct_h + //octave_stdout << "Byte read " << bytesRead << " of a total of "<< bytesToRead << "\n"; +#endif } else { @@ -85,7 +92,7 @@ bool RiaSocketDataTransfer::readBlockDataFromSocket(QTcpSocket* socket, char* da } } -// Allow Octave process to end a long running Octave function + // Allow Octave process to end a long running Octave function #ifdef octave_oct_h OCTAVE_QUIT; #endif @@ -98,8 +105,9 @@ bool RiaSocketDataTransfer::readBlockDataFromSocket(QTcpSocket* socket, char* da //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RiaSocketDataTransfer::doubleValueCountInBlock() +size_t RiaSocketDataTransfer::maximumValueCountInBlock() { - return 2000; + return 20000; } + diff --git a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.h b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.h index 06ae14b379..7c16beb8aa 100644 --- a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.h +++ b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.h @@ -28,7 +28,7 @@ class RiaSocketDataTransfer { public: - static size_t doubleValueCountInBlock(); + static size_t maximumValueCountInBlock(); public: static bool writeBlockDataToSocket(QTcpSocket* socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages); From 62a2c9e3cee6c278b28d92d2b2d658fce3dda39a Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 24 Apr 2014 08:32:43 +0200 Subject: [PATCH 093/130] Fixed mock models --- .../ProjectDataModel/RimResultCase.cpp | 14 +------------- .../RigReservoirBuilderMock.cpp | 17 +++-------------- 2 files changed, 4 insertions(+), 27 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimResultCase.cpp b/ApplicationCode/ProjectDataModel/RimResultCase.cpp index a392121b5f..d0d72587fa 100644 --- a/ApplicationCode/ProjectDataModel/RimResultCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultCase.cpp @@ -211,21 +211,9 @@ cvf::ref RimResultCase::createMockModel(QString modelName) mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(20, 20, 20)); mockFileInterface->setGridPointDimensions(cvf::Vec3st(4, 5, 6)); mockFileInterface->addLocalGridRefinement(cvf::Vec3st(0, 2, 2), cvf::Vec3st(0, 2, 2), cvf::Vec3st(3, 3, 3)); + mockFileInterface->enableWellData(false); mockFileInterface->open("", reservoir.p()); - { - size_t idx = reservoir->mainGrid()->cellIndexFromIJK(1, 3, 4); - - //TODO: Rewrite active cell info in mock models - //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); - } - - { - size_t idx = reservoir->mainGrid()->cellIndexFromIJK(2, 2, 3); - - //TODO: Rewrite active cell info in mock models - //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); - } } else if (modelName == RimDefines::mockModelBasicWithResults()) { diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp index 221bb9db1b..33367e9378 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp @@ -137,12 +137,13 @@ void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCoun size_t activeCellIndex = 0; long long i; - cells.resize(cellCount); + size_t cellIndexStart = cells.size(); + cells.resize(cells.size() + cellCount); #pragma omp parallel for for (i = 0; i < static_cast(cellCount); i++) { - RigCell& riCell = cells[i]; + RigCell& riCell = cells[cellIndexStart + i]; riCell.setHostGrid(hostGrid); riCell.setCellIndex(i); @@ -157,18 +158,6 @@ void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCoun riCell.cornerIndices()[7] = nodeStartIndex + i * 8 + 7; riCell.setParentCellIndex(0); - - //TODO: Rewrite active cell info in mock models - /* - if (!(i % 5)) - { - riCell.setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); - } - else - { - riCell.setActiveIndexInMatrixModel(activeCellIndex++); - } - */ } } From 366c3cd2e848ee54b40744b51d253a3e668c408a Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 24 Apr 2014 09:52:46 +0200 Subject: [PATCH 094/130] Performance: Use OpenMP for static data --- .../ReservoirDataModel/RigReservoirBuilderMock.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp index 33367e9378..ec981ebc21 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp @@ -312,13 +312,12 @@ bool RigReservoirBuilderMock::inputProperty(RigCaseData* eclipseCase, const QStr //-------------------------------------------------------------------------------------------------- bool RigReservoirBuilderMock::staticResult(RigCaseData* eclipseCase, const QString& result, std::vector* values) { - size_t k; + values->resize(eclipseCase->mainGrid()->cells().size()); - for (k = 0; k < eclipseCase->mainGrid()->cells().size(); k++) +#pragma omp parallel for + for (long long k = 0; k < static_cast(eclipseCase->mainGrid()->cells().size()); k++) { - { - values->push_back((k * 2) % eclipseCase->mainGrid()->cells().size()); - } + values->at(k) = (k * 2) % eclipseCase->mainGrid()->cells().size(); } return false; From d3456ffcc941f4f86bfb4775512488743290b412 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 24 Apr 2014 09:53:40 +0200 Subject: [PATCH 095/130] Performance: Use OpenMP for fault calculations --- ApplicationCode/ReservoirDataModel/RigMainGrid.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp b/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp index 0c93dbf975..bef2c7c9c5 100644 --- a/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp +++ b/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp @@ -227,7 +227,8 @@ void RigMainGrid::calculateFaults() RigFault * unNamedFault = new RigFault; int unNamedFaultIdx = static_cast(m_faults.size()); - for (size_t gcIdx = 0 ; gcIdx < m_cells.size(); ++gcIdx) +#pragma omp parallel for + for (int gcIdx = 0 ; gcIdx < static_cast(m_cells.size()); ++gcIdx) { if ( m_cells[gcIdx].isInvalid()) { @@ -298,8 +299,12 @@ void RigMainGrid::calculateFaults() if (gcIdx < neighborGlobalCellIdx) { - RigFault::FaultFace ff(gcIdx, cvf::StructGridInterface::FaceType(faceIdx), neighborGlobalCellIdx); - unNamedFault->faultFaces().push_back(ff); + #pragma omp critical + { + RigFault::FaultFace ff(gcIdx, cvf::StructGridInterface::FaceType(faceIdx), neighborGlobalCellIdx); + unNamedFault->faultFaces().push_back(ff); + } + } else { From dbe54ff9bf2d7b25634b48d70401596bf4a06a40 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 24 Apr 2014 10:25:22 +0200 Subject: [PATCH 096/130] Performance: Reverted OpenMP, as the function needs rewrite --- ApplicationCode/ReservoirDataModel/RigMainGrid.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp b/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp index bef2c7c9c5..10d6ae9aaf 100644 --- a/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp +++ b/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp @@ -227,7 +227,6 @@ void RigMainGrid::calculateFaults() RigFault * unNamedFault = new RigFault; int unNamedFaultIdx = static_cast(m_faults.size()); -#pragma omp parallel for for (int gcIdx = 0 ; gcIdx < static_cast(m_cells.size()); ++gcIdx) { if ( m_cells[gcIdx].isInvalid()) @@ -299,7 +298,6 @@ void RigMainGrid::calculateFaults() if (gcIdx < neighborGlobalCellIdx) { - #pragma omp critical { RigFault::FaultFace ff(gcIdx, cvf::StructGridInterface::FaceType(faceIdx), neighborGlobalCellIdx); unNamedFault->faultFaces().push_back(ff); From 2e45fc41cb2c5d38f53ce5ca8d35f9405294e3ed Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 25 Apr 2014 08:39:42 +0200 Subject: [PATCH 097/130] Improved robustness for reading faults --- .../RifEclipseInputFileTools.cpp | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp index 34009e4340..d2ddac49a8 100644 --- a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp @@ -671,13 +671,13 @@ qint64 RifEclipseInputFileTools::findKeyword(const QString& keyword, QFile& file do { line = file.readLine(); + line = line.trimmed(); + if (line.startsWith("--", Qt::CaseInsensitive)) { continue; } - line = line.trimmed(); - if (line.startsWith(keyword, Qt::CaseInsensitive)) { return file.pos(); @@ -706,6 +706,8 @@ bool RifEclipseInputFileTools::readFaultsAndParseIncludeStatementsRecursively(QF do { line = file.readLine(); + line = line.trimmed(); + if (line.startsWith("--", Qt::CaseInsensitive)) { continue; @@ -720,14 +722,19 @@ bool RifEclipseInputFileTools::readFaultsAndParseIncludeStatementsRecursively(QF return false; } - - line = line.trimmed(); if (line.startsWith(includeKeyword, Qt::CaseInsensitive)) { - QString nextLine = file.readLine(); + line = file.readLine(); + line = line.trimmed(); + + while (line.startsWith("--", Qt::CaseInsensitive)) + { + line = file.readLine(); + line = line.trimmed(); + } - int firstQuote = nextLine.indexOf("'"); - int lastQuote = nextLine.lastIndexOf("'"); + int firstQuote = line.indexOf("'"); + int lastQuote = line.lastIndexOf("'"); if (!(firstQuote < 0 || lastQuote < 0 || firstQuote == lastQuote)) { @@ -738,7 +745,7 @@ bool RifEclipseInputFileTools::readFaultsAndParseIncludeStatementsRecursively(QF } // Read include file name, and both relative and absolute path is supported - QString includeFilename = nextLine.mid(firstQuote + 1, lastQuote - firstQuote - 1); + QString includeFilename = line.mid(firstQuote + 1, lastQuote - firstQuote - 1); QFileInfo fi(currentFileFolder, includeFilename); if (fi.exists()) { From cbc3238180da08003d6fc2b7ec8459915fb5e84c Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 25 Apr 2014 09:59:41 +0200 Subject: [PATCH 098/130] Do not show progress info when running from unit tests --- Fwk/AppFwk/cafUserInterface/cafProgressInfo.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Fwk/AppFwk/cafUserInterface/cafProgressInfo.cpp b/Fwk/AppFwk/cafUserInterface/cafProgressInfo.cpp index 03847fdc3b..94abc195ba 100644 --- a/Fwk/AppFwk/cafUserInterface/cafProgressInfo.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafProgressInfo.cpp @@ -76,7 +76,10 @@ ProgressInfo::ProgressInfo(size_t maxProgressValue, const QString& title) { ProgressInfoStatic::start(maxProgressValue, title); - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + if (qApp) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + } } //-------------------------------------------------------------------------------------------------- @@ -86,7 +89,10 @@ ProgressInfo::~ProgressInfo() { ProgressInfoStatic::finished(); - QApplication::restoreOverrideCursor(); + if (qApp) + { + QApplication::restoreOverrideCursor(); + } } //-------------------------------------------------------------------------------------------------- From 3608c362916ffa591fc119ab0f7edd7533c761ae Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 25 Apr 2014 12:13:09 +0200 Subject: [PATCH 099/130] Added test to guard for invalid cell index --- ApplicationCode/ReservoirDataModel/RigFault.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ApplicationCode/ReservoirDataModel/RigFault.cpp b/ApplicationCode/ReservoirDataModel/RigFault.cpp index d96b5776be..6bfaba0dca 100644 --- a/ApplicationCode/ReservoirDataModel/RigFault.cpp +++ b/ApplicationCode/ReservoirDataModel/RigFault.cpp @@ -119,7 +119,7 @@ void RigFault::computeFaultFacesFromCellRanges(const RigMainGrid* mainGrid) size_t ni, nj, nk; mainGrid->neighborIJKAtCellFace(i, j, k, faceEnum, &ni, &nj, &nk); - if (ni != cvf::UNDEFINED_SIZE_T && nj != cvf::UNDEFINED_SIZE_T && nk != cvf::UNDEFINED_SIZE_T) + if (ni < mainGrid->cellCountI() && nj < mainGrid->cellCountJ() && nk < mainGrid->cellCountK()) { size_t localCellIndex = mainGrid->cellIndexFromIJK(i, j, k); size_t oppositeCellIndex = mainGrid->cellIndexFromIJK(ni, nj, nk); From 585f034799554f698e0407ddca67317ac9cc0609 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 25 Apr 2014 14:36:34 +0200 Subject: [PATCH 100/130] Bugfix: Get pointer to data after adding data to std vector When SOIL is created, a new dataset is appended to a std vector. Pointer to SWAT and SGAS data must be aquired AFTER the new dataset is added. Adding data to a vector can trigger reallocation of data. --- .../RimReservoirCellResultsCacher.cpp | 56 +++++++++++-------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.cpp b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.cpp index 3d7231630d..9b3357a8e1 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.cpp @@ -56,7 +56,7 @@ CAF_PDM_SOURCE_INIT(RimReservoirCellResultsStorage, "ReservoirCellResultStorage" //-------------------------------------------------------------------------------------------------- RimReservoirCellResultsStorage::RimReservoirCellResultsStorage() : m_cellResults(NULL), - m_ownerMainGrid(NULL) + m_ownerMainGrid(NULL) { CAF_PDM_InitObject("Cacher", "", "", ""); @@ -136,7 +136,7 @@ void RimReservoirCellResultsStorage::setupBeforeSave() // If there is no data, we do not store anything for the current result variable // (Even not the metadata, of cause) size_t timestepCount = m_cellResults->cellScalarResults(resInfo[rIdx].m_gridScalarResultIndex).size(); - + if (timestepCount && resInfo[rIdx].m_needsToBeStored) { progInfo.setProgressDescription(resInfo[rIdx].m_resultName); @@ -251,7 +251,7 @@ size_t RimReservoirCellResultsStorage::findOrLoadScalarResultForTimeStep(RimDefi if (soilScalarResultIndex == cvf::UNDEFINED_SIZE_T) { computeSOILForTimeStep(timeStepIndex); - + soilScalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName); return soilScalarResultIndex; } @@ -419,32 +419,22 @@ void RimReservoirCellResultsStorage::computeSOILForTimeStep(size_t timeStepIndex size_t soilResultValueCount = 0; size_t soilTimeStepCount = 0; - std::vector* swatForTimeStep = NULL; - std::vector* sgasForTimeStep = NULL; if (scalarIndexSWAT != cvf::UNDEFINED_SIZE_T) { - swatForTimeStep = &(m_cellResults->cellScalarResults(scalarIndexSWAT, timeStepIndex)); - if (swatForTimeStep->size() == 0) + std::vector& swatForTimeStep = m_cellResults->cellScalarResults(scalarIndexSWAT, timeStepIndex); + if (swatForTimeStep.size() > 0) { - swatForTimeStep = NULL; - } - else - { - soilResultValueCount = swatForTimeStep->size(); + soilResultValueCount = swatForTimeStep.size(); soilTimeStepCount = m_cellResults->infoForEachResultIndex()[scalarIndexSWAT].m_timeStepDates.size(); } } if (scalarIndexSGAS != cvf::UNDEFINED_SIZE_T) { - sgasForTimeStep = &(m_cellResults->cellScalarResults(scalarIndexSGAS, timeStepIndex)); - if (sgasForTimeStep->size() == 0) + std::vector& sgasForTimeStep = m_cellResults->cellScalarResults(scalarIndexSGAS, timeStepIndex); + if (sgasForTimeStep.size() > 0) { - sgasForTimeStep = NULL; - } - else - { - soilResultValueCount = qMax(soilResultValueCount, sgasForTimeStep->size()); + soilResultValueCount = qMax(soilResultValueCount, sgasForTimeStep.size()); size_t sgasTimeStepCount = m_cellResults->infoForEachResultIndex()[scalarIndexSGAS].m_timeStepDates.size(); soilTimeStepCount = qMax(soilTimeStepCount, sgasTimeStepCount); @@ -468,6 +458,28 @@ void RimReservoirCellResultsStorage::computeSOILForTimeStep(size_t timeStepIndex } } + + std::vector* swatForTimeStep = NULL; + std::vector* sgasForTimeStep = NULL; + + if (scalarIndexSWAT != cvf::UNDEFINED_SIZE_T) + { + swatForTimeStep = &(m_cellResults->cellScalarResults(scalarIndexSWAT, timeStepIndex)); + if (swatForTimeStep->size() == 0) + { + swatForTimeStep = NULL; + } + } + + if (scalarIndexSGAS != cvf::UNDEFINED_SIZE_T) + { + sgasForTimeStep = &(m_cellResults->cellScalarResults(scalarIndexSGAS, timeStepIndex)); + if (sgasForTimeStep->size() == 0) + { + sgasForTimeStep = NULL; + } + } + std::vector& soilForTimeStep = m_cellResults->cellScalarResults(soilResultGridIndex, timeStepIndex); #pragma omp parallel for @@ -514,7 +526,7 @@ void RimReservoirCellResultsStorage::computeDepthRelatedResults() if (depthResultGridIndex == cvf::UNDEFINED_SIZE_T) { - depthResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DEPTH", false, resultValueCount); + depthResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DEPTH", false, resultValueCount); computeDepth = true; } @@ -694,7 +706,7 @@ void RimReservoirCellResultsStorage::setCellResults(RigCaseCellResultsData* cell for (size_t tsIdx = 0; tsIdx < resInfo->m_timeStepDates().size(); ++tsIdx) { std::vector* data = NULL; - + data = &(m_cellResults->cellScalarResults(rIdx, tsIdx)); quint64 cellCount = 0; @@ -760,4 +772,4 @@ RimReservoirCellResultsStorageEntryInfo::RimReservoirCellResultsStorageEntryInfo RimReservoirCellResultsStorageEntryInfo::~RimReservoirCellResultsStorageEntryInfo() { -} +} \ No newline at end of file From 0c3e54b130fdf77d0b43bacd22b13f7acc1a6345 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 25 Apr 2014 16:32:06 +0200 Subject: [PATCH 101/130] Ternary: Added possibility to switch between local and global range --- .../ProjectDataModel/RimLegendConfig.cpp | 21 ++++++++++++++++++- .../ProjectDataModel/RimLegendConfig.h | 10 ++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp index 8a53df3136..124f3b8e52 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp @@ -112,7 +112,7 @@ RimLegendConfig::RimLegendConfig() CAF_PDM_InitField(&m_colorRangeMode, "ColorRangeMode", ColorRangeEnum(NORMAL) , "Colors", "", "", ""); CAF_PDM_InitField(&m_mappingMode, "MappingMode", MappingEnum(LINEAR_CONTINUOUS) , "Mapping", "", "", ""); - CAF_PDM_InitField(&m_rangeMode, "RangeType", caf::AppEnum(AUTOMATIC_ALLTIMESTEPS), "Range type", "", "Switches between automatic and user defined range on the legend", ""); + CAF_PDM_InitField(&m_rangeMode, "RangeType", RangeModeEnum(AUTOMATIC_ALLTIMESTEPS), "Range type", "", "Switches between automatic and user defined range on the legend", ""); CAF_PDM_InitField(&m_userDefinedMaxValue, "UserDefinedMax", 1.0, "Max", "", "Min value of the legend", ""); CAF_PDM_InitField(&m_userDefinedMinValue, "UserDefinedMin", 0.0, "Min", "", "Max value of the legend", ""); CAF_PDM_InitField(&resultVariableName, "ResultVariableUsage", QString(""), "", "", "", ""); @@ -653,6 +653,8 @@ void RimLegendConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& // caf::PdmUiOrdering * formatGr = uiOrdering.addNewGroup("Ternary format"); // formatGr->add(&m_mappingMode); // formatGr->add(&m_numLevels); + caf::PdmUiOrdering * mappingGr = uiOrdering.addNewGroup("Mapping"); + mappingGr->add(&m_rangeMode); uiOrdering.setForgetRemainingFields(true); } @@ -700,8 +702,25 @@ QList RimLegendConfig::calculateValueOptions(const caf:: return optionList; } + + if (fieldNeedingOptions == &m_rangeMode) + { + QList optionList; + optionList.push_back(caf::PdmOptionItemInfo(RangeModeEnum(AUTOMATIC_ALLTIMESTEPS).uiText(), AUTOMATIC_ALLTIMESTEPS)); + optionList.push_back(caf::PdmOptionItemInfo(RangeModeEnum(AUTOMATIC_CURRENT_TIMESTEP).uiText(), AUTOMATIC_CURRENT_TIMESTEP)); + + return optionList; + } } return QList(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimLegendConfig::RangeModeType RimLegendConfig::rangeMode() const +{ + return m_rangeMode(); +} + diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.h b/ApplicationCode/ProjectDataModel/RimLegendConfig.h index 117eefcc7c..183acca583 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.h +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.h @@ -54,12 +54,14 @@ class RimLegendConfig: public caf::PdmObject caf::PdmField resultVariableName; // Used internally to describe the variable this legend setup is used for - enum RangeModeType + enum RangeModeType { AUTOMATIC_ALLTIMESTEPS, AUTOMATIC_CURRENT_TIMESTEP, USER_DEFINED }; + + typedef caf::AppEnum RangeModeEnum; enum ColorRangesType { @@ -95,6 +97,8 @@ class RimLegendConfig: public caf::PdmObject cvf::OverlayScalarMapperLegend* legend() { return m_legend.p(); } int linearDiscreteLevelCount() const; + RangeModeType rangeMode() const; + protected: virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); @@ -106,7 +110,7 @@ class RimLegendConfig: public caf::PdmObject cvf::ref interpolateColorArray(const cvf::Color3ubArray& colorArray, cvf::uint targetColorCount); double roundToNumSignificantDigits(double value, double precision); - virtual QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly ); + virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly); private: @@ -136,7 +140,7 @@ class RimLegendConfig: public caf::PdmObject caf::PdmField m_numLevels; caf::PdmField m_precision; caf::PdmField > m_tickNumberFormat; - caf::PdmField > m_rangeMode; + caf::PdmField m_rangeMode; caf::PdmField m_userDefinedMaxValue; caf::PdmField m_userDefinedMinValue; caf::PdmField > m_colorRangeMode; From 83a5a34c4b3314360008f9bf77ac42d4f9750d6d Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 25 Apr 2014 16:32:41 +0200 Subject: [PATCH 102/130] Ternary: Compute color based on local/global min/max values --- .../ModelVisualization/RivGridPartMgr.cpp | 95 +++++++++++++++++-- 1 file changed, 86 insertions(+), 9 deletions(-) diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index 306aa3ec2f..cce46a68e4 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -50,6 +50,7 @@ #include "cvfUniform.h" #include "cvfShaderSourceProvider.h" #include "cvfShaderProgram.h" +#include "cvfMath.h" @@ -656,32 +657,108 @@ void RivTransmissibilityColorMapper::updateTernarySaturationColorArray(size_t ti RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); + double soilMin = 0.0; + double soilMax = 1.0; + double sgasMin = 0.0; + double sgasMax = 1.0; + double swatMin = 0.0; + double swatMax = 1.0; + cvf::ref dataAccessObjectSoil = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, soilScalarSetIndex); - if (dataAccessObjectSoil.isNull()) dataAccessObjectSoil = new ScalarDataAccessZeroForAllCells; + if (dataAccessObjectSoil.notNull()) + { + if (cellResultSlot->legendConfig()->rangeMode() == RimLegendConfig::AUTOMATIC_CURRENT_TIMESTEP) + { + gridCellResults->cellResults()->minMaxCellScalarValues(soilScalarSetIndex, timeStepIndex, soilMin, soilMax); + } + else + { + gridCellResults->cellResults()->minMaxCellScalarValues(soilScalarSetIndex, soilMin, soilMax); + } + } + else + { + dataAccessObjectSoil = new ScalarDataAccessZeroForAllCells; + } cvf::ref dataAccessObjectSgas = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, sgasScalarSetIndex); - if (dataAccessObjectSgas.isNull()) dataAccessObjectSgas = new ScalarDataAccessZeroForAllCells; + if (dataAccessObjectSgas.notNull()) + { + if (cellResultSlot->legendConfig()->rangeMode() == RimLegendConfig::AUTOMATIC_CURRENT_TIMESTEP) + { + gridCellResults->cellResults()->minMaxCellScalarValues(sgasScalarSetIndex, timeStepIndex, sgasMin, sgasMax); + } + else + { + gridCellResults->cellResults()->minMaxCellScalarValues(sgasScalarSetIndex, sgasMin, sgasMax); + } + } + else + { + dataAccessObjectSgas = new ScalarDataAccessZeroForAllCells; + } cvf::ref dataAccessObjectSwat = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, swatScalarSetIndex); - if (dataAccessObjectSwat.isNull()) dataAccessObjectSwat = new ScalarDataAccessZeroForAllCells; + if (dataAccessObjectSwat.notNull()) + { + if (cellResultSlot->legendConfig()->rangeMode() == RimLegendConfig::AUTOMATIC_CURRENT_TIMESTEP) + { + gridCellResults->cellResults()->minMaxCellScalarValues(swatScalarSetIndex, timeStepIndex, swatMin, swatMax); + } + else + { + gridCellResults->cellResults()->minMaxCellScalarValues(swatScalarSetIndex, swatMin, swatMax); + } + } + else + { + dataAccessObjectSwat = new ScalarDataAccessZeroForAllCells; + } + + double soilRange = soilMax - soilMin; + double soilFactor = 255.0 / soilRange; + + double sgasRange = sgasMax - sgasMin; + double sgasFactor = 255.0 / sgasRange; + + double swatRange = swatMax - swatMin; + double swatFactor = 255.0 / swatRange; size_t numVertices = quadsToGridCells.size()*4; colorArray->resize(numVertices); - cvf::Color3f ternaryColor; cvf::Color3ub ternaryColorByte; + double v, vNormalized; -#pragma omp parallel for private(ternaryColor, ternaryColorByte) +#pragma omp parallel for private(ternaryColorByte, v, vNormalized) for (int idx = 0; idx < static_cast(quadsToGridCells.size()); idx++) { size_t gridCellIndex = quadsToGridCells[idx]; - ternaryColor.r() = dataAccessObjectSgas->cellScalar(gridCellIndex); - ternaryColor.g() = dataAccessObjectSoil->cellScalar(gridCellIndex); - ternaryColor.b() = dataAccessObjectSwat->cellScalar(gridCellIndex); + { + v = dataAccessObjectSgas->cellScalar(gridCellIndex); + vNormalized = (v - sgasMin) * sgasFactor; + + vNormalized = cvf::Math::clamp(vNormalized, 0.0, 255.0); + ternaryColorByte.r() = vNormalized; + } + + { + v = dataAccessObjectSoil->cellScalar(gridCellIndex); + vNormalized = (v - soilMin) * soilFactor; - ternaryColorByte.set(ternaryColor.rByte(), ternaryColor.gByte(), ternaryColor.bByte()); + vNormalized = cvf::Math::clamp(vNormalized, 0.0, 255.0); + ternaryColorByte.g() = vNormalized; + } + + { + v = dataAccessObjectSwat->cellScalar(gridCellIndex); + vNormalized = (v - swatMin) * swatFactor; + + vNormalized = cvf::Math::clamp(vNormalized, 0.0, 255.0); + ternaryColorByte.b() = vNormalized; + } size_t j; for (j = 0; j < 4; j++) From 3b651d757859f384ac886d859d2c622c30d995f0 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 29 Apr 2014 10:13:19 +0200 Subject: [PATCH 103/130] Show ternary saturation data on faults --- .../ModelVisualization/RivFaultPartMgr.cpp | 80 ++++++++++++++++--- .../ModelVisualization/RivGridPartMgr.cpp | 10 +-- .../ModelVisualization/RivGridPartMgr.h | 3 +- 3 files changed, 74 insertions(+), 19 deletions(-) diff --git a/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp b/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp index 1486a69ce4..33e3474d97 100644 --- a/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp @@ -105,6 +105,7 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* updateNNCColors(cellResultSlot); + size_t scalarSetIndex = cellResultSlot->gridScalarIndex(); const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper(); @@ -117,12 +118,19 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); cvf::ref dataAccessObject = eclipseCase->dataAccessObject(m_grid.p(), porosityModel, resTimeStepIdx, scalarSetIndex); - if (dataAccessObject.isNull()) return; - // Faults if (m_nativeFaultFaces.notNull()) { - if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) + cvf::ref surfaceFacesColorArray; + if (cellResultSlot->isTernarySaturationSelected()) + { + surfaceFacesColorArray = new cvf::Color3ubArray; + + const std::vector& quadsToGridCells = m_nativeFaultGenerator->quadToGridCellIndices(); + + RivTransmissibilityColorMapper::updateTernarySaturationColorArray(timeStepIndex, cellResultSlot, m_grid.p(), surfaceFacesColorArray.p(), quadsToGridCells); + } + else if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) { const std::vector& quadsToFaceTypes = m_nativeFaultGenerator->quadToFace(); const std::vector& quadsToGridCells = m_nativeFaultGenerator->quadToGridCellIndices(); @@ -132,7 +140,10 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* } else { - m_nativeFaultGenerator->textureCoordinates(m_nativeFaultFacesTextureCoords.p(), dataAccessObject.p(), mapper); + if (dataAccessObject.notNull()) + { + m_nativeFaultGenerator->textureCoordinates(m_nativeFaultFacesTextureCoords.p(), dataAccessObject.p(), mapper); + } } if (m_opacityLevel < 1.0f ) @@ -159,16 +170,41 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* } cvf::DrawableGeo* dg = dynamic_cast(m_nativeFaultFaces->drawable()); - if (dg) dg->setTextureCoordArray(m_nativeFaultFacesTextureCoords.p()); + if (surfaceFacesColorArray.notNull()) + { + if (dg) + { + dg->setColorArray(surfaceFacesColorArray.p()); + } - cvf::ref scalarEffect = cellResultEffect(mapper, caf::PO_1); - m_nativeFaultFaces->setEffect(scalarEffect.p()); + cvf::ref perVertexColorEffect = RivGridPartMgr::createPerVertexColoringEffect(m_opacityLevel); + m_nativeFaultFaces->setEffect(perVertexColorEffect.p()); + + m_nativeFaultFaces->setPriority(100); + } + else + { + if (dg) dg->setTextureCoordArray(m_nativeFaultFacesTextureCoords.p()); + + cvf::ref scalarEffect = cellResultEffect(mapper, caf::PO_1); + m_nativeFaultFaces->setEffect(scalarEffect.p()); + } } if (m_oppositeFaultFaces.notNull()) { - if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) + cvf::ref surfaceFacesColorArray; + + if (cellResultSlot->isTernarySaturationSelected()) + { + surfaceFacesColorArray = new cvf::Color3ubArray; + + const std::vector& quadsToGridCells = m_oppositeFaultGenerator->quadToGridCellIndices(); + + RivTransmissibilityColorMapper::updateTernarySaturationColorArray(timeStepIndex, cellResultSlot, m_grid.p(), surfaceFacesColorArray.p(), quadsToGridCells); + } + else if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) { const std::vector& quadsToFaceTypes = m_oppositeFaultGenerator->quadToFace(); const std::vector& quadsToGridCells = m_oppositeFaultGenerator->quadToGridCellIndices(); @@ -178,7 +214,10 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* } else { - m_oppositeFaultGenerator->textureCoordinates(m_oppositeFaultFacesTextureCoords.p(), dataAccessObject.p(), mapper); + if (dataAccessObject.notNull()) + { + m_oppositeFaultGenerator->textureCoordinates(m_oppositeFaultFacesTextureCoords.p(), dataAccessObject.p(), mapper); + } } if (m_opacityLevel < 1.0f ) @@ -205,12 +244,27 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* } cvf::DrawableGeo* dg = dynamic_cast(m_oppositeFaultFaces->drawable()); - if (dg) dg->setTextureCoordArray(m_oppositeFaultFacesTextureCoords.p()); + if (surfaceFacesColorArray.notNull()) + { + if (dg) + { + dg->setColorArray(surfaceFacesColorArray.p()); + } + + cvf::ref perVertexColorEffect = RivGridPartMgr::createPerVertexColoringEffect(m_opacityLevel); + m_oppositeFaultFaces->setEffect(perVertexColorEffect.p()); + + m_oppositeFaultFaces->setPriority(100); + } + else + { + if (dg) dg->setTextureCoordArray(m_oppositeFaultFacesTextureCoords.p()); - // Use a different offset than native fault faces to avoid z-fighting - cvf::ref scalarEffect = cellResultEffect(mapper, caf::PO_2); + // Use a different offset than native fault faces to avoid z-fighting + cvf::ref scalarEffect = cellResultEffect(mapper, caf::PO_2); - m_oppositeFaultFaces->setEffect(scalarEffect.p()); + m_oppositeFaultFaces->setEffect(scalarEffect.p()); + } } } diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index cce46a68e4..0fd2c81b9e 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -334,7 +334,7 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* dg->setColorArray(surfaceFacesColorArray.p()); } - cvf::ref perVertexColorEffect = createPerVertexColoringEffect(); + cvf::ref perVertexColorEffect = RivGridPartMgr::createPerVertexColoringEffect(m_opacityLevel); m_surfaceFaces->setEffect(perVertexColorEffect.p()); m_surfaceFaces->setPriority(100); @@ -472,7 +472,7 @@ RivGridPartMgr::~RivGridPartMgr() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RivGridPartMgr::createPerVertexColoringEffect() +cvf::ref RivGridPartMgr::createPerVertexColoringEffect(float opacity) { cvf::ref colorArrayEffect = new cvf::Effect; @@ -485,14 +485,14 @@ cvf::ref RivGridPartMgr::createPerVertexColoringEffect() gen.addFragmentCode(cvf::ShaderSourceRepository::fs_Standard); cvf::ref m_shaderProg = gen.generate(); - m_shaderProg->setDefaultUniform(new cvf::UniformFloat("u_alpha", m_opacityLevel)); + m_shaderProg->setDefaultUniform(new cvf::UniformFloat("u_alpha", opacity)); colorArrayEffect->setShaderProgram(m_shaderProg.p()); } else { cvf::ref mat = new cvf::RenderStateMaterial_FF(cvf::Color3::BLUE); - mat->setAlpha(m_opacityLevel); + mat->setAlpha(opacity); mat->enableColorMaterial(true); colorArrayEffect->setRenderState(mat.p()); @@ -502,7 +502,7 @@ cvf::ref RivGridPartMgr::createPerVertexColoringEffect() } // Simple transparency - if (m_opacityLevel < 1.0f) + if (opacity < 1.0f) { cvf::ref blender = new cvf::RenderStateBlending; blender->configureTransparencyBlending(); diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.h b/ApplicationCode/ModelVisualization/RivGridPartMgr.h index a33d435fb8..d205256381 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.h @@ -87,9 +87,10 @@ class RivGridPartMgr: public cvf::Object void appendPartsToModel(cvf::ModelBasicList* model); + static cvf::ref createPerVertexColoringEffect(float opacity); + private: void generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder, bool faultGeometry); - cvf::ref createPerVertexColoringEffect(); private: size_t m_gridIdx; From 7c6ff0c533824eb63b4694b426ddab4c972197ab Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 6 May 2014 22:39:53 +0200 Subject: [PATCH 104/130] Added ternary legend config Included user defined ranges for SOIL, SGAS, SWAT --- .../ModelVisualization/RivGridPartMgr.cpp | 42 +- .../ProjectDataModel/CMakeLists_files.cmake | 2 + .../ProjectDataModel/RimReservoirView.cpp | 54 ++- .../ProjectDataModel/RimReservoirView.h | 2 - .../ProjectDataModel/RimResultSlot.cpp | 74 ++-- .../ProjectDataModel/RimResultSlot.h | 6 +- .../RimTernaryLegendConfig.cpp | 405 ++++++++++++++++++ .../ProjectDataModel/RimTernaryLegendConfig.h | 107 +++++ 8 files changed, 619 insertions(+), 73 deletions(-) create mode 100644 ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp create mode 100644 ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index 0fd2c81b9e..4bcb6a0f1a 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -31,6 +31,7 @@ #include "RigCaseData.h" #include "RiaApplication.h" #include "RiaPreferences.h" +#include "RimTernaryLegendConfig.h" #include "RimCase.h" #include "RimWellCollection.h" @@ -664,53 +665,22 @@ void RivTransmissibilityColorMapper::updateTernarySaturationColorArray(size_t ti double swatMin = 0.0; double swatMax = 1.0; + cellResultSlot->ternaryLegendConfig()->ternaryRanges(soilMin, soilMax, sgasMin, sgasMax, swatMin, swatMax); + cvf::ref dataAccessObjectSoil = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, soilScalarSetIndex); - if (dataAccessObjectSoil.notNull()) - { - if (cellResultSlot->legendConfig()->rangeMode() == RimLegendConfig::AUTOMATIC_CURRENT_TIMESTEP) - { - gridCellResults->cellResults()->minMaxCellScalarValues(soilScalarSetIndex, timeStepIndex, soilMin, soilMax); - } - else - { - gridCellResults->cellResults()->minMaxCellScalarValues(soilScalarSetIndex, soilMin, soilMax); - } - } - else + if (dataAccessObjectSoil.isNull()) { dataAccessObjectSoil = new ScalarDataAccessZeroForAllCells; } cvf::ref dataAccessObjectSgas = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, sgasScalarSetIndex); - if (dataAccessObjectSgas.notNull()) - { - if (cellResultSlot->legendConfig()->rangeMode() == RimLegendConfig::AUTOMATIC_CURRENT_TIMESTEP) - { - gridCellResults->cellResults()->minMaxCellScalarValues(sgasScalarSetIndex, timeStepIndex, sgasMin, sgasMax); - } - else - { - gridCellResults->cellResults()->minMaxCellScalarValues(sgasScalarSetIndex, sgasMin, sgasMax); - } - } - else + if (dataAccessObjectSgas.isNull()) { dataAccessObjectSgas = new ScalarDataAccessZeroForAllCells; } cvf::ref dataAccessObjectSwat = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, swatScalarSetIndex); - if (dataAccessObjectSwat.notNull()) - { - if (cellResultSlot->legendConfig()->rangeMode() == RimLegendConfig::AUTOMATIC_CURRENT_TIMESTEP) - { - gridCellResults->cellResults()->minMaxCellScalarValues(swatScalarSetIndex, timeStepIndex, swatMin, swatMax); - } - else - { - gridCellResults->cellResults()->minMaxCellScalarValues(swatScalarSetIndex, swatMin, swatMax); - } - } - else + if (dataAccessObjectSwat.isNull()) { dataAccessObjectSwat = new ScalarDataAccessZeroForAllCells; } diff --git a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake index 4e0d185f37..1b265e3dd2 100644 --- a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake @@ -47,6 +47,7 @@ ${CEE_CURRENT_LIST_DIR}RimTools.h ${CEE_CURRENT_LIST_DIR}RimFault.h ${CEE_CURRENT_LIST_DIR}RimFaultCollection.h ${CEE_CURRENT_LIST_DIR}RimMockModelSettings.h +${CEE_CURRENT_LIST_DIR}RimTernaryLegendConfig.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -92,6 +93,7 @@ ${CEE_CURRENT_LIST_DIR}RimTools.cpp ${CEE_CURRENT_LIST_DIR}RimFault.cpp ${CEE_CURRENT_LIST_DIR}RimFaultCollection.cpp ${CEE_CURRENT_LIST_DIR}RimMockModelSettings.cpp +${CEE_CURRENT_LIST_DIR}RimTernaryLegendConfig.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp index 58e81185a3..6e83c97a77 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp @@ -45,6 +45,7 @@ #include "RimCaseCollection.h" #include "RimOilField.h" #include "RimAnalysisModels.h" +#include "RimTernaryLegendConfig.h" #include "RiuMainWindow.h" #include "RigGridBase.h" @@ -232,6 +233,7 @@ void RimReservoirView::updateViewerWidget() RiuMainWindow::instance()->addViewer(m_viewer); m_viewer->setMinNearPlaneDistance(10); this->cellResult()->legendConfig->recreateLegend(); + this->cellResult()->ternaryLegendConfig->recreateLegend(); this->cellEdgeResult()->legendConfig->recreateLegend(); m_viewer->setColorLegend1(this->cellResult()->legendConfig->legend()); m_viewer->setColorLegend2(this->cellEdgeResult()->legendConfig->legend()); @@ -1448,21 +1450,55 @@ void RimReservoirView::updateLegends() this->cellEdgeResult()->legendConfig->setAutomaticRanges(cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE); } - if (m_ternarySaturationOverlayItem.notNull()) - { - viewer()->removeOverlayItem(m_ternarySaturationOverlayItem.p()); - } + + viewer()->removeOverlayItem(this->cellResult()->ternaryLegendConfig->legend()); if (this->cellResult()->isTernarySaturationSelected()) { - if (m_ternarySaturationOverlayItem.isNull()) + RimReservoirCellResultsStorage* gridCellResults = this->cellResult()->currentGridCellResults(); { - cvf::Font* standardFont = RiaApplication::instance()->standardFont(); - m_ternarySaturationOverlayItem = new RivTernarySaturationOverlayItem(standardFont); - m_ternarySaturationOverlayItem->setLayout(cvf::OverlayItem::VERTICAL, cvf::OverlayItem::BOTTOM_LEFT); + double globalMin = 0.0; + double globalMax = 1.0; + double localMin = 0.0; + double localMax = 1.0; + + size_t scalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); + results->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax); + results->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax); + + this->cellResult()->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SOIL_IDX, globalMin, globalMax, localMin, localMax); } - viewer()->addOverlayItem(m_ternarySaturationOverlayItem.p()); + { + double globalMin = 0.0; + double globalMax = 1.0; + double localMin = 0.0; + double localMax = 1.0; + + size_t scalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); + results->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax); + results->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax); + + this->cellResult()->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SGAS_IDX, globalMin, globalMax, localMin, localMax); + } + + { + double globalMin = 0.0; + double globalMax = 1.0; + double localMin = 0.0; + double localMax = 1.0; + + size_t scalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); + results->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax); + results->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax); + + this->cellResult()->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SWAT_IDX, globalMin, globalMax, localMin, localMax); + } + + if (this->cellResult()->ternaryLegendConfig->legend()) + { + viewer()->addOverlayItem(this->cellResult()->ternaryLegendConfig->legend()); + } } } diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.h b/ApplicationCode/ProjectDataModel/RimReservoirView.h index 955eeada1b..a45a6c2e1d 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.h +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.h @@ -201,8 +201,6 @@ class RimReservoirView : public caf::PdmObject cvf::ref m_reservoirGridPartManager; cvf::ref m_pipesPartManager; - cvf::ref m_ternarySaturationOverlayItem; - // Overridden PDM methods: public: virtual caf::PdmFieldHandle* userDescriptionField() { return &name; } diff --git a/ApplicationCode/ProjectDataModel/RimResultSlot.cpp b/ApplicationCode/ProjectDataModel/RimResultSlot.cpp index e7bdec4640..7c5b888179 100644 --- a/ApplicationCode/ProjectDataModel/RimResultSlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultSlot.cpp @@ -36,6 +36,7 @@ #include "Rim3dOverlayInfoConfig.h" #include "RimReservoirCellResultsCacher.h" +#include "RimTernaryLegendConfig.h" CAF_PDM_SOURCE_INIT(RimResultSlot, "ResultSlot"); @@ -51,6 +52,9 @@ RimResultSlot::RimResultSlot() m_legendConfigData.setUiHidden(true); m_legendConfigData.setUiChildrenHidden(true); + CAF_PDM_InitFieldNoDefault(&ternaryLegendConfig, "TernaryLegendDefinition", "Ternary Legend Definition", "", "", ""); + ternaryLegendConfig = new RimTernaryLegendConfig(); + legendConfig = new RimLegendConfig(); } @@ -60,6 +64,7 @@ RimResultSlot::RimResultSlot() RimResultSlot::~RimResultSlot() { delete legendConfig(); + delete ternaryLegendConfig(); } //-------------------------------------------------------------------------------------------------- @@ -91,36 +96,52 @@ void RimResultSlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, co //-------------------------------------------------------------------------------------------------- void RimResultSlot::changeLegendConfig(QString resultVarNameOfNewLegend) { - if (this->legendConfig()->resultVariableName() == resultVarNameOfNewLegend) return; - - std::list >::iterator it; - bool found = false; - for (it = m_legendConfigData.v().begin(); it != m_legendConfigData.v().end(); ++it) + if (resultVarNameOfNewLegend == RimDefines::ternarySaturationResultName()) { - if ((*it)->resultVariableName() == resultVarNameOfNewLegend) + this->ternaryLegendConfig.setUiHidden(false); + this->ternaryLegendConfig.setUiChildrenHidden(false); + this->legendConfig.setUiHidden(true); + this->legendConfig.setUiChildrenHidden(true); + } + else + { + this->ternaryLegendConfig.setUiHidden(true); + this->ternaryLegendConfig.setUiChildrenHidden(true); + + if (this->legendConfig()->resultVariableName() != resultVarNameOfNewLegend) { - RimLegendConfig* newLegend = *it; + std::list >::iterator it; + bool found = false; + for (it = m_legendConfigData.v().begin(); it != m_legendConfigData.v().end(); ++it) + { + if ((*it)->resultVariableName() == resultVarNameOfNewLegend) + { + RimLegendConfig* newLegend = *it; - m_legendConfigData.v().erase(it); - m_legendConfigData.v().push_back(this->legendConfig()); - this->legendConfig = newLegend; - RiuMainWindow::instance()->uiPdmModel()->updateUiSubTree(this); - found = true; - break; + m_legendConfigData.v().erase(it); + m_legendConfigData.v().push_back(this->legendConfig()); + this->legendConfig = newLegend; + found = true; + break; + } + } + + // Not found ? + if (!found) + { + RimLegendConfig* newLegend = new RimLegendConfig; + newLegend->setReservoirView(m_reservoirView); + newLegend->resultVariableName = resultVarNameOfNewLegend; + m_legendConfigData.v().push_back(this->legendConfig()); + this->legendConfig = newLegend; + } } + + this->legendConfig.setUiHidden(false); + this->legendConfig.setUiChildrenHidden(false); } - // Not found ? - if (!found) - { - RimLegendConfig* newLegend = new RimLegendConfig; - newLegend->setReservoirView(m_reservoirView); - newLegend->resultVariableName = resultVarNameOfNewLegend; - m_legendConfigData.v().push_back(this->legendConfig()); - this->legendConfig = newLegend; - RiuMainWindow::instance()->uiPdmModel()->updateUiSubTree(this); - - } + RiuMainWindow::instance()->uiPdmModel()->updateUiSubTree(this); } //-------------------------------------------------------------------------------------------------- @@ -134,6 +155,8 @@ void RimResultSlot::initAfterRead() { this->legendConfig()->resultVariableName = this->resultVariable(); } + + changeLegendConfig(this->resultVariable()); } //-------------------------------------------------------------------------------------------------- @@ -148,4 +171,7 @@ void RimResultSlot::setReservoirView(RimReservoirView* ownerReservoirView) { (*it)->setReservoirView(ownerReservoirView); } + + if (ternaryLegendConfig) ternaryLegendConfig->setReservoirView(ownerReservoirView); } + diff --git a/ApplicationCode/ProjectDataModel/RimResultSlot.h b/ApplicationCode/ProjectDataModel/RimResultSlot.h index 29c91a68f2..97e84ff8b6 100644 --- a/ApplicationCode/ProjectDataModel/RimResultSlot.h +++ b/ApplicationCode/ProjectDataModel/RimResultSlot.h @@ -24,6 +24,8 @@ #include "RimDefines.h" #include "RimResultDefinition.h" +class RimTernaryLegendConfig; + //================================================================================================== /// /// @@ -37,6 +39,7 @@ class RimResultSlot : public RimResultDefinition virtual void setReservoirView(RimReservoirView* ownerReservoirView); caf::PdmField legendConfig; + caf::PdmField ternaryLegendConfig; // Overridden methods virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); @@ -46,7 +49,6 @@ class RimResultSlot : public RimResultDefinition private: void changeLegendConfig(QString resultVarNameOfNewLegend); - caf::PdmField > > m_legendConfigData; - + caf::PdmField > > m_legendConfigData; }; diff --git a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp new file mode 100644 index 0000000000..77a78b9e6a --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp @@ -0,0 +1,405 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RimTernaryLegendConfig.h" + +#include "cafPdmUiPushButtonEditor.h" +#include "cafPdmUiTextEditor.h" + +#include "RiaApplication.h" +#include "RimReservoirView.h" + +#include "RivTernarySaturationOverlayItem.h" + + +CAF_PDM_SOURCE_INIT(RimTernaryLegendConfig, "RimTernaryLegendConfig"); + +namespace caf { + template<> + void AppEnum::setUp() + { + addItem(RimTernaryLegendConfig::AUTOMATIC_ALLTIMESTEPS, "AUTOMATIC_ALLTIMESTEPS", "Global range"); + addItem(RimTernaryLegendConfig::AUTOMATIC_CURRENT_TIMESTEP,"AUTOMATIC_CURRENT_TIMESTEP", "Local range"); + addItem(RimTernaryLegendConfig::USER_DEFINED, "USER_DEFINED_MAX_MIN", "User defined range"); + setDefault(RimTernaryLegendConfig::AUTOMATIC_ALLTIMESTEPS); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimTernaryLegendConfig::RimTernaryLegendConfig() +{ + CAF_PDM_InitObject("Ternary Legend Definition", ":/Legend.png", "", ""); + + CAF_PDM_InitField(&precision, "Precision", 2, "Significant digits", "", "The number of significant digits displayed in the legend numbers",""); + CAF_PDM_InitField(&rangeMode, "RangeType", RangeModeEnum(USER_DEFINED), "Range type", "", "Switches between automatic and user defined range on the legend", ""); + + CAF_PDM_InitFieldNoDefault(&applyLocalMinMax, "m_applyLocalMinMax", "", "", "", ""); + applyLocalMinMax.setIOWritable(false); + applyLocalMinMax.setIOReadable(false); + applyLocalMinMax.setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); + applyLocalMinMax.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + applyLocalMinMax = false; + + CAF_PDM_InitFieldNoDefault(&applyGlobalMinMax, "m_applyGlobalMinMax", "", "", "", ""); + applyGlobalMinMax.setIOWritable(false); + applyGlobalMinMax.setIOReadable(false); + applyGlobalMinMax.setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); + applyGlobalMinMax.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + applyGlobalMinMax = false; + + CAF_PDM_InitFieldNoDefault(&applyFullRangeMinMax, "m_applyFullRangeMinMax", "", "", "", ""); + applyFullRangeMinMax.setIOWritable(false); + applyFullRangeMinMax.setIOReadable(false); + applyFullRangeMinMax.setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); + applyFullRangeMinMax.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + applyFullRangeMinMax = false; + + CAF_PDM_InitFieldNoDefault(&ternaryRangeSummary, "ternaryRangeSummary", "Range summary", "", "", ""); + ternaryRangeSummary.setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); + ternaryRangeSummary.setUiLabelPosition(caf::PdmUiItemInfo::TOP); + + + CAF_PDM_InitField(&userDefinedMaxValueSoil, "UserDefinedMaxSoil", 1.0, "Max", "", "Min value of the legend", ""); + CAF_PDM_InitField(&userDefinedMinValueSoil, "UserDefinedMinSoil", 0.0, "Min", "", "Max value of the legend", ""); + + CAF_PDM_InitField(&userDefinedMaxValueSgas, "UserDefinedMaxSgas", 1.0, "Max", "", "Min value of the legend", ""); + CAF_PDM_InitField(&userDefinedMinValueSgas, "UserDefinedMinSgas", 0.0, "Min", "", "Max value of the legend", ""); + + CAF_PDM_InitField(&userDefinedMaxValueSwat, "UserDefinedMaxSwat", 1.0, "Max", "", "Min value of the legend", ""); + CAF_PDM_InitField(&userDefinedMinValueSwat, "UserDefinedMinSwat", 0.0, "Min", "", "Max value of the legend", ""); + + m_globalAutoMin.resize(3, 0.0); + m_globalAutoMax.resize(3, 1.0); + m_localAutoMin.resize(3, 0.0); + m_localAutoMax.resize(3, 1.0); + + recreateLegend(); + updateLegend(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimTernaryLegendConfig::~RimTernaryLegendConfig() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTernaryLegendConfig::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + if (changedField == &applyLocalMinMax) + { + userDefinedMaxValueSoil = m_localAutoMax[TERNARY_SOIL_IDX]; + userDefinedMinValueSoil = m_localAutoMin[TERNARY_SOIL_IDX]; + userDefinedMaxValueSgas = m_localAutoMax[TERNARY_SGAS_IDX]; + userDefinedMinValueSgas = m_localAutoMin[TERNARY_SGAS_IDX]; + userDefinedMaxValueSwat = m_localAutoMax[TERNARY_SWAT_IDX]; + userDefinedMinValueSwat = m_localAutoMin[TERNARY_SWAT_IDX]; + + applyLocalMinMax = false; + } + else if (changedField == &applyGlobalMinMax) + { + userDefinedMaxValueSoil = m_globalAutoMax[TERNARY_SOIL_IDX]; + userDefinedMinValueSoil = m_globalAutoMin[TERNARY_SOIL_IDX]; + userDefinedMaxValueSgas = m_globalAutoMax[TERNARY_SGAS_IDX]; + userDefinedMinValueSgas = m_globalAutoMin[TERNARY_SGAS_IDX]; + userDefinedMaxValueSwat = m_globalAutoMax[TERNARY_SWAT_IDX]; + userDefinedMinValueSwat = m_globalAutoMin[TERNARY_SWAT_IDX]; + + applyGlobalMinMax = false; + } + else if (changedField == &applyFullRangeMinMax) + { + userDefinedMaxValueSoil = 1.0; + userDefinedMinValueSoil = 0.0; + userDefinedMaxValueSgas = 1.0; + userDefinedMinValueSgas = 0.0; + userDefinedMaxValueSwat = 1.0; + userDefinedMinValueSwat = 0.0; + + applyFullRangeMinMax = false; + } + + updateLabelText(); + updateLegend(); + + if (m_reservoirView) m_reservoirView->updateCurrentTimeStepAndRedraw(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTernaryLegendConfig::updateLegend() +{ + // TODO: Update text on ternary legend +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTernaryLegendConfig::setAutomaticRanges(TernaryArrayIndex ternaryIndex, double globalMin, double globalMax, double localMin, double localMax) +{ + double candidateGlobalAutoMin = roundToNumSignificantDigits(globalMin, precision); + double candidateGlobalAutoMax = roundToNumSignificantDigits(globalMax, precision); + + double candidateLocalAutoMin = roundToNumSignificantDigits(localMin, precision); + double candidateLocalAutoMax = roundToNumSignificantDigits(localMax, precision); + + m_globalAutoMin[ternaryIndex] = candidateGlobalAutoMin; + m_globalAutoMax[ternaryIndex] = candidateGlobalAutoMax; + m_localAutoMin[ternaryIndex] = candidateLocalAutoMin; + m_localAutoMax[ternaryIndex] = candidateLocalAutoMax; + + updateLabelText(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTernaryLegendConfig::recreateLegend() +{ + // Due to possible visualization bug, we need to recreate the legend if the last viewer + // has been removed, (and thus the opengl resources has been deleted) The text in + // the legend disappeared because of this, so workaround: recreate the legend when needed: + + cvf::Font* standardFont = RiaApplication::instance()->standardFont(); + m_legend = new RivTernarySaturationOverlayItem(standardFont); + m_legend->setLayout(cvf::OverlayItem::VERTICAL, cvf::OverlayItem::BOTTOM_LEFT); + + updateLegend(); +} + +//-------------------------------------------------------------------------------------------------- +/// Rounding the double value to given number of significant digits +//-------------------------------------------------------------------------------------------------- +double RimTernaryLegendConfig::roundToNumSignificantDigits(double domainValue, double numSignificantDigits) +{ + double absDomainValue = cvf::Math::abs(domainValue); + if (absDomainValue == 0.0) + { + return 0.0; + } + + double logDecValue = log10(absDomainValue); + logDecValue = cvf::Math::ceil(logDecValue); + + double factor = pow(10.0, numSignificantDigits - logDecValue); + + double tmp = domainValue * factor; + double integerPart; + double fraction = modf(tmp, &integerPart); + + if (cvf::Math::abs(fraction)>= 0.5) (integerPart >= 0) ? integerPart++: integerPart-- ; + + double newDomainValue = integerPart / factor; + + return newDomainValue; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTernaryLegendConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + caf::PdmUiOrdering* formatGr = uiOrdering.addNewGroup("Format"); + formatGr->add(&precision); + formatGr->add(&rangeMode); + + if (rangeMode == USER_DEFINED) + { + caf::PdmUiOrdering* ternaryGroupContainer = uiOrdering.addNewGroup("Ternary "); + { + caf::PdmUiOrdering* ternaryGroup = ternaryGroupContainer->addNewGroup("SOIL"); + ternaryGroup->add(&userDefinedMinValueSoil); + ternaryGroup->add(&userDefinedMaxValueSoil); + } + + { + caf::PdmUiOrdering* ternaryGroup = ternaryGroupContainer->addNewGroup("SGAS"); + ternaryGroup->add(&userDefinedMinValueSgas); + ternaryGroup->add(&userDefinedMaxValueSgas); + } + + { + caf::PdmUiOrdering* ternaryGroup = ternaryGroupContainer->addNewGroup("SWAT"); + ternaryGroup->add(&userDefinedMinValueSwat); + ternaryGroup->add(&userDefinedMaxValueSwat); + } + + ternaryGroupContainer->add(&applyLocalMinMax); + ternaryGroupContainer->add(&applyGlobalMinMax); + ternaryGroupContainer->add(&applyFullRangeMinMax); + } + else + { + caf::PdmUiOrdering* group = uiOrdering.addNewGroup("Summary"); + group->add(&ternaryRangeSummary); + } + + uiOrdering.setForgetRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::OverlayItem* RimTernaryLegendConfig::legend() +{ + return m_legend.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTernaryLegendConfig::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) +{ + if (&applyLocalMinMax == field) + { + caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast (attribute); + if (attrib) + { + attrib->m_buttonText = "Apply local min/max values"; + } + } + else if (&applyGlobalMinMax == field) + { + caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast (attribute); + if (attrib) + { + attrib->m_buttonText = "Apply global min/max values"; + } + } + else if (&applyFullRangeMinMax == field) + { + caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast (attribute); + if (attrib) + { + attrib->m_buttonText = "Apply full range"; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTernaryLegendConfig::ternaryRanges(double& soilLower, double& soilUpper, double& sgasLower, double& sgasUpper, double& swatLower, double& swatUpper) const +{ + if (rangeMode() == AUTOMATIC_CURRENT_TIMESTEP) + { + soilLower = m_localAutoMin[TERNARY_SOIL_IDX]; + soilUpper = m_localAutoMax[TERNARY_SOIL_IDX]; + sgasLower = m_localAutoMin[TERNARY_SGAS_IDX]; + sgasUpper = m_localAutoMax[TERNARY_SGAS_IDX]; + swatLower = m_localAutoMin[TERNARY_SWAT_IDX]; + swatUpper = m_localAutoMax[TERNARY_SWAT_IDX]; + } + else if (rangeMode() == AUTOMATIC_ALLTIMESTEPS) + { + soilLower = m_globalAutoMin[TERNARY_SOIL_IDX]; + soilUpper = m_globalAutoMax[TERNARY_SOIL_IDX]; + sgasLower = m_globalAutoMin[TERNARY_SGAS_IDX]; + sgasUpper = m_globalAutoMax[TERNARY_SGAS_IDX]; + swatLower = m_globalAutoMin[TERNARY_SWAT_IDX]; + swatUpper = m_globalAutoMax[TERNARY_SWAT_IDX]; + } + else + { + soilLower = userDefinedMinValueSoil; + soilUpper = userDefinedMaxValueSoil; + sgasLower = userDefinedMinValueSgas; + sgasUpper = userDefinedMaxValueSgas; + swatLower = userDefinedMinValueSwat; + swatUpper = userDefinedMaxValueSwat; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTernaryLegendConfig::updateLabelText() +{ + { + userDefinedMinValueSoil.setUiName("Min"); + userDefinedMaxValueSoil.setUiName("Max"); + + if (m_globalAutoMin[TERNARY_SOIL_IDX] != cvf::UNDEFINED_DOUBLE ) + { + userDefinedMinValueSoil.setUiName(QString("Min ") + "(" + QString::number(m_globalAutoMin[TERNARY_SOIL_IDX], 'g', precision) + ")"); + } + + if (m_globalAutoMax[TERNARY_SOIL_IDX] != cvf::UNDEFINED_DOUBLE ) + { + userDefinedMaxValueSoil.setUiName(QString("Max ") + "(" + QString::number(m_globalAutoMax[TERNARY_SOIL_IDX], 'g', precision) + ")"); + } + } + + { + userDefinedMinValueSgas.setUiName("Min"); + userDefinedMaxValueSgas.setUiName("Max"); + + if (m_globalAutoMin[TERNARY_SGAS_IDX] != cvf::UNDEFINED_DOUBLE ) + { + userDefinedMinValueSgas.setUiName(QString("Min ") + "(" + QString::number(m_globalAutoMin[TERNARY_SGAS_IDX], 'g', precision) + ")"); + } + + if (m_globalAutoMax[TERNARY_SGAS_IDX] != cvf::UNDEFINED_DOUBLE ) + { + userDefinedMaxValueSgas.setUiName(QString("Max ") + "(" + QString::number(m_globalAutoMax[TERNARY_SGAS_IDX], 'g', precision) + ")"); + } + } + + { + userDefinedMinValueSwat.setUiName("Min"); + userDefinedMaxValueSwat.setUiName("Max"); + + if (m_globalAutoMin[TERNARY_SWAT_IDX] != cvf::UNDEFINED_DOUBLE ) + { + userDefinedMinValueSwat.setUiName(QString("Min ") + "(" + QString::number(m_globalAutoMin[TERNARY_SWAT_IDX], 'g', precision) + ")"); + } + + if (m_globalAutoMax[TERNARY_SWAT_IDX] != cvf::UNDEFINED_DOUBLE ) + { + userDefinedMaxValueSwat.setUiName(QString("Max ") + "(" + QString::number(m_globalAutoMax[TERNARY_SWAT_IDX], 'g', precision) + ")"); + } + } + + if (rangeMode == AUTOMATIC_ALLTIMESTEPS) + { + QString tmpString; + tmpString = QString("SOIL : ") + QString::number(m_globalAutoMin[TERNARY_SOIL_IDX], 'g', precision) + " - " + QString::number(m_globalAutoMax[TERNARY_SOIL_IDX], 'g', precision) + "\n"; + tmpString += QString("SGAS : ") + QString::number(m_globalAutoMin[TERNARY_SGAS_IDX], 'g', precision) + " - " + QString::number(m_globalAutoMax[TERNARY_SGAS_IDX], 'g', precision) + "\n"; + tmpString += QString("SWAT : ") + QString::number(m_globalAutoMin[TERNARY_SWAT_IDX], 'g', precision) + " - " + QString::number(m_globalAutoMax[TERNARY_SWAT_IDX], 'g', precision) + "\n"; + + ternaryRangeSummary = tmpString; + } + else if (rangeMode == AUTOMATIC_CURRENT_TIMESTEP) + { + QString tmpString; + tmpString = QString("SOIL : ") + QString::number(m_localAutoMin[TERNARY_SOIL_IDX], 'g', precision) + " - " + QString::number(m_localAutoMax[TERNARY_SOIL_IDX], 'g', precision) + "\n"; + tmpString += QString("SGAS : ") + QString::number(m_localAutoMin[TERNARY_SGAS_IDX], 'g', precision) + " - " + QString::number(m_localAutoMax[TERNARY_SGAS_IDX], 'g', precision) + "\n"; + tmpString += QString("SWAT : ") + QString::number(m_localAutoMin[TERNARY_SWAT_IDX], 'g', precision) + " - " + QString::number(m_localAutoMax[TERNARY_SWAT_IDX], 'g', precision) + "\n"; + + ternaryRangeSummary = tmpString; + } +} + diff --git a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h new file mode 100644 index 0000000000..0e21420d84 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h @@ -0,0 +1,107 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "cvfObject.h" + +#include "cafAppEnum.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +class RimReservoirView; +class RivTernarySaturationOverlayItem; + +namespace cvf +{ + class OverlayItem; +} + + + +//================================================================================================== +/// +/// +//================================================================================================== +class RimTernaryLegendConfig : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + enum TernaryArrayIndex + { + TERNARY_SOIL_IDX = 0, + TERNARY_SGAS_IDX, + TERNARY_SWAT_IDX + }; + + enum RangeModeType + { + AUTOMATIC_ALLTIMESTEPS, + AUTOMATIC_CURRENT_TIMESTEP, + USER_DEFINED + }; + typedef caf::AppEnum RangeModeEnum; + +public: + RimTernaryLegendConfig(); + virtual ~RimTernaryLegendConfig(); + + void setReservoirView(RimReservoirView* ownerReservoirView) {m_reservoirView = ownerReservoirView; } + + void setAutomaticRanges(TernaryArrayIndex ternaryIndex, double globalMin, double globalMax, double localMin, double localMax); + void ternaryRanges(double& soilLower, double& soilUpper, double& sgasLower, double& sgasUpper, double& swatLower, double& swatUpper) const; + + void recreateLegend(); + cvf::OverlayItem* legend(); + +protected: + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering ); + virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); + +private: + void updateLegend(); + void updateLabelText(); + double roundToNumSignificantDigits(double value, double precision); + + +private: + caf::PdmField precision; + caf::PdmField rangeMode; + + caf::PdmField userDefinedMaxValueSoil; + caf::PdmField userDefinedMinValueSoil; + caf::PdmField userDefinedMaxValueSgas; + caf::PdmField userDefinedMinValueSgas; + caf::PdmField userDefinedMaxValueSwat; + caf::PdmField userDefinedMinValueSwat; + + caf::PdmField applyLocalMinMax; + caf::PdmField applyGlobalMinMax; + caf::PdmField applyFullRangeMinMax; + caf::PdmField ternaryRangeSummary; + + std::vector m_globalAutoMax; + std::vector m_globalAutoMin; + std::vector m_localAutoMax; + std::vector m_localAutoMin; + + caf::PdmPointer m_reservoirView; + cvf::ref m_legend; +}; From 918f2c43052d6be39ef0a8331165e6a461bc46e8 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 6 May 2014 22:40:25 +0200 Subject: [PATCH 105/130] Removed ternary specific code and cleaned up includes --- .../ProjectDataModel/RimLegendConfig.cpp | 96 ++----------------- .../ProjectDataModel/RimLegendConfig.h | 5 - 2 files changed, 9 insertions(+), 92 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp index 124f3b8e52..3cfd96ca48 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp @@ -18,27 +18,23 @@ #include "RimLegendConfig.h" -#include "RimReservoirView.h" #include "cafFactory.h" -#include "cafPdmUiLineEditor.h" +#include "cafPdmFieldCvfColor.h" +#include "cafPdmFieldCvfMat4d.h" #include "cafPdmUiComboBoxEditor.h" +#include "cafPdmUiLineEditor.h" -#include "cvfScalarMapperDiscreteLog.h" -#include "cvfScalarMapperContinuousLog.h" -#include "cvfScalarMapperContinuousLinear.h" #include "cvfOverlayScalarMapperLegend.h" +#include "cvfScalarMapperContinuousLinear.h" +#include "cvfScalarMapperContinuousLog.h" #include "cvfScalarMapperDiscreteLinear.h" +#include "cvfScalarMapperDiscreteLog.h" + #include #include "RiaApplication.h" -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" +#include "RimReservoirView.h" + CAF_PDM_SOURCE_INIT(RimLegendConfig, "Legend"); @@ -480,18 +476,6 @@ void RimLegendConfig::updateFieldVisibility() m_userDefinedMaxValue.setUiHidden(true); m_userDefinedMinValue.setUiHidden(true); } - - if (m_reservoirView && m_reservoirView->cellResult() && m_reservoirView->cellResult()->isTernarySaturationSelected()) - { - if (m_mappingMode == LINEAR_DISCRETE) - { - m_numLevels.setUiHidden(false); - } - else - { - m_numLevels.setUiHidden(true); - } - } } //-------------------------------------------------------------------------------------------------- @@ -647,18 +631,6 @@ void RimLegendConfig::setClosestToZeroValues(double globalPosClosestToZero, doub //-------------------------------------------------------------------------------------------------- void RimLegendConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { - if (m_reservoirView && m_reservoirView->cellResult() && m_reservoirView->cellResult()->isTernarySaturationSelected()) - { - //TODO: Add support for discrete legend -// caf::PdmUiOrdering * formatGr = uiOrdering.addNewGroup("Ternary format"); -// formatGr->add(&m_mappingMode); -// formatGr->add(&m_numLevels); - caf::PdmUiOrdering * mappingGr = uiOrdering.addNewGroup("Mapping"); - mappingGr->add(&m_rangeMode); - - uiOrdering.setForgetRemainingFields(true); - } - else { caf::PdmUiOrdering * formatGr = uiOrdering.addNewGroup("Format"); formatGr->add(&m_numLevels); @@ -674,53 +646,3 @@ void RimLegendConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& } } -//-------------------------------------------------------------------------------------------------- -/// Return the number of levels if mapping mode is LINEAR_DISCRETE, else -1 -//-------------------------------------------------------------------------------------------------- -int RimLegendConfig::linearDiscreteLevelCount() const -{ - if (m_mappingMode == LINEAR_DISCRETE) - { - return m_numLevels; - } - - return -1; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QList RimLegendConfig::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) -{ - if (m_reservoirView && m_reservoirView->cellResult() && m_reservoirView->cellResult()->isTernarySaturationSelected()) - { - if (fieldNeedingOptions == &m_mappingMode) - { - QList optionList; - optionList.push_back(caf::PdmOptionItemInfo(MappingEnum(LINEAR_DISCRETE).uiText(), LINEAR_DISCRETE)); - optionList.push_back(caf::PdmOptionItemInfo(MappingEnum(LINEAR_CONTINUOUS).uiText(), LINEAR_CONTINUOUS)); - - return optionList; - } - - if (fieldNeedingOptions == &m_rangeMode) - { - QList optionList; - optionList.push_back(caf::PdmOptionItemInfo(RangeModeEnum(AUTOMATIC_ALLTIMESTEPS).uiText(), AUTOMATIC_ALLTIMESTEPS)); - optionList.push_back(caf::PdmOptionItemInfo(RangeModeEnum(AUTOMATIC_CURRENT_TIMESTEP).uiText(), AUTOMATIC_CURRENT_TIMESTEP)); - - return optionList; - } - } - - return QList(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimLegendConfig::RangeModeType RimLegendConfig::rangeMode() const -{ - return m_rangeMode(); -} - diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.h b/ApplicationCode/ProjectDataModel/RimLegendConfig.h index 183acca583..a8a697601d 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.h +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.h @@ -96,9 +96,6 @@ class RimLegendConfig: public caf::PdmObject cvf::ScalarMapper* scalarMapper() { return m_currentScalarMapper.p(); } cvf::OverlayScalarMapperLegend* legend() { return m_legend.p(); } - int linearDiscreteLevelCount() const; - RangeModeType rangeMode() const; - protected: virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); @@ -110,8 +107,6 @@ class RimLegendConfig: public caf::PdmObject cvf::ref interpolateColorArray(const cvf::Color3ubArray& colorArray, cvf::uint targetColorCount); double roundToNumSignificantDigits(double value, double precision); - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly); - private: caf::PdmPointer m_reservoirView; From 89dd686261d332db6a3a03d98ab85723c4b109c0 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 6 May 2014 22:50:49 +0200 Subject: [PATCH 106/130] Added missing include on Linux --- ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp index 77a78b9e6a..eecc6d1875 100644 --- a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp +++ b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp @@ -26,6 +26,8 @@ #include "RivTernarySaturationOverlayItem.h" +#include + CAF_PDM_SOURCE_INIT(RimTernaryLegendConfig, "RimTernaryLegendConfig"); From 625a6b5f0eeab801653aff4dfe0386e007cda727 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 6 May 2014 22:51:17 +0200 Subject: [PATCH 107/130] Cleaned up includes --- .../ModelVisualization/RivGridPartMgr.cpp | 52 +++++++++---------- .../ProjectDataModel/RimResultSlot.cpp | 19 ++----- .../ProjectDataModel/RimResultSlot.h | 5 +- 3 files changed, 30 insertions(+), 46 deletions(-) diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index 4bcb6a0f1a..c209a4d578 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -18,42 +18,38 @@ #include "RivGridPartMgr.h" -#include "cvfPart.h" -#include "cafEffectGenerator.h" -#include "cvfStructGrid.h" -#include "cvfDrawableGeo.h" -#include "cvfModelBasicList.h" -#include "RivCellEdgeEffectGenerator.h" -#include "RimReservoirView.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RigCaseCellResultsData.h" -#include "RigCaseData.h" -#include "RiaApplication.h" -#include "RiaPreferences.h" -#include "RimTernaryLegendConfig.h" -#include "RimCase.h" -#include "RimWellCollection.h" -#include "cafPdmFieldCvfMat4d.h" +#include "cafEffectGenerator.h" #include "cafPdmFieldCvfColor.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimReservoirCellResultsCacher.h" -#include "RivSourceInfo.h" -#include "cvfRenderState_FF.h" +#include "cafPdmFieldCvfMat4d.h" #include "cafProgressInfo.h" -#include "cvfRenderStatePolygonOffset.h" +#include "cvfDrawableGeo.h" +#include "cvfMath.h" +#include "cvfModelBasicList.h" +#include "cvfPart.h" #include "cvfRenderStateBlending.h" +#include "cvfRenderStatePolygonOffset.h" +#include "cvfRenderState_FF.h" +#include "cvfShaderProgram.h" #include "cvfShaderProgramGenerator.h" +#include "cvfShaderSourceProvider.h" #include "cvfShaderSourceRepository.h" +#include "cvfStructGrid.h" #include "cvfUniform.h" -#include "cvfShaderSourceProvider.h" -#include "cvfShaderProgram.h" -#include "cvfMath.h" - +#include "RiaApplication.h" +#include "RiaPreferences.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RimCase.h" +#include "RimCellEdgeResultSlot.h" +#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirView.h" +#include "RimResultSlot.h" +#include "RimTernaryLegendConfig.h" +#include "RimWellCollection.h" +#include "RivCellEdgeEffectGenerator.h" +#include "RivSourceInfo.h" //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimResultSlot.cpp b/ApplicationCode/ProjectDataModel/RimResultSlot.cpp index 7c5b888179..5e4e6452b0 100644 --- a/ApplicationCode/ProjectDataModel/RimResultSlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultSlot.cpp @@ -19,24 +19,11 @@ #include "RiaStdInclude.h" #include "RimResultSlot.h" -#include "RimLegendConfig.h" -#include "RimReservoirView.h" -#include "RimCase.h" -#include "RiuMainWindow.h" -#include "RimUiTreeModelPdm.h" - -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" - -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirView.h" #include "RimTernaryLegendConfig.h" +#include "RimUiTreeModelPdm.h" +#include "RiuMainWindow.h" CAF_PDM_SOURCE_INIT(RimResultSlot, "ResultSlot"); diff --git a/ApplicationCode/ProjectDataModel/RimResultSlot.h b/ApplicationCode/ProjectDataModel/RimResultSlot.h index 97e84ff8b6..a5b9ec909d 100644 --- a/ApplicationCode/ProjectDataModel/RimResultSlot.h +++ b/ApplicationCode/ProjectDataModel/RimResultSlot.h @@ -18,10 +18,11 @@ #pragma once -#include "cafPdmObject.h" -#include "RimLegendConfig.h" #include "cafAppEnum.h" +#include "cafPdmObject.h" + #include "RimDefines.h" +#include "RimLegendConfig.h" #include "RimResultDefinition.h" class RimTernaryLegendConfig; From cc4e9eb5058253c86be16a184ac47ab5524299c4 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 6 May 2014 23:29:03 +0200 Subject: [PATCH 108/130] Make sure size_t is defined on Linux --- ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h index 0e21420d84..6697441da9 100644 --- a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h +++ b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h @@ -18,6 +18,7 @@ #pragma once +#include "cvfBase.h" #include "cvfObject.h" #include "cafAppEnum.h" From bed902d005a8d7eab3bbe314c6321943b1d46b2f Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 6 May 2014 23:29:41 +0200 Subject: [PATCH 109/130] Show ternary range on overlay item --- .../RivTernarySaturationOverlayItem.cpp | 20 +++++++++-- .../RivTernarySaturationOverlayItem.h | 6 ++++ .../RimTernaryLegendConfig.cpp | 35 ++++++++++++++++++- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp index 565dbc21eb..cdfcfc5fd5 100644 --- a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp +++ b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp @@ -121,9 +121,15 @@ void RivTernarySaturationOverlayItem::render(cvf::OpenGLContext* oglContext, con cvf::TextDrawer textDrawer(m_font.p()); textDrawer.setTextColor(m_textColor); - textDrawer.addText("SWAT", cvf::Vec2f(0.0, 0.0)); - textDrawer.addText("SOIL", cvf::Vec2f(static_cast(size.x() - 28), 0.0)); + textDrawer.addText("SWAT", cvf::Vec2f(0.0, 10.0)); + textDrawer.addText(m_swatRange, cvf::Vec2f(0.0, 0.0)); + + textDrawer.addText("SOIL", cvf::Vec2f(static_cast(size.x() - 40), 10.0)); + textDrawer.addText(m_soilRange, cvf::Vec2f(static_cast(size.x() - 40), 0.0)); + textDrawer.addText("SGAS", cvf::Vec2f(static_cast( (size.x() / 2) - 17 ), static_cast(size.y() - 10))); + textDrawer.addText(m_sgasRange, cvf::Vec2f(static_cast( (size.x() / 2) - 17 ), static_cast(size.y() - 20))); + textDrawer.renderSoftware(oglContext, camera); renderAxisImmediateMode(oglContext); @@ -197,4 +203,14 @@ void RivTernarySaturationOverlayItem::renderAxisImmediateMode(cvf::OpenGLContext } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivTernarySaturationOverlayItem::setRangeText(const cvf::String& soilRange, const cvf::String& sgasRange, const cvf::String& swatRange) +{ + m_soilRange = soilRange; + m_sgasRange = sgasRange; + m_swatRange = swatRange; +} + diff --git a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h index eb03b4d90a..ca145cf496 100644 --- a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h +++ b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h @@ -40,6 +40,8 @@ class RivTernarySaturationOverlayItem : public cvf::OverlayItem RivTernarySaturationOverlayItem(cvf::Font* font); ~RivTernarySaturationOverlayItem(); + void setRangeText(const cvf::String& soilRange, const cvf::String& sgasRange, const cvf::String& swatRange); + virtual cvf::Vec2ui sizeHint(); virtual void render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size); @@ -56,6 +58,10 @@ class RivTernarySaturationOverlayItem : public cvf::OverlayItem private: cvf::Color3f m_textColor; // Text color cvf::ref m_font; + + cvf::String m_soilRange; + cvf::String m_sgasRange; + cvf::String m_swatRange; cvf::Vec2ui m_size; // Pixel size of draw area }; diff --git a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp index eecc6d1875..4f5a9bcde6 100644 --- a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp +++ b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp @@ -27,6 +27,7 @@ #include "RivTernarySaturationOverlayItem.h" #include +#include "cvfqtUtils.h" CAF_PDM_SOURCE_INIT(RimTernaryLegendConfig, "RimTernaryLegendConfig"); @@ -154,7 +155,39 @@ void RimTernaryLegendConfig::fieldChangedByUi(const caf::PdmFieldHandle* changed //-------------------------------------------------------------------------------------------------- void RimTernaryLegendConfig::updateLegend() { - // TODO: Update text on ternary legend + double soilLower = 0.0; + double soilUpper = 1.0; + double sgasLower = 0.0; + double sgasUpper = 1.0; + double swatLower = 0.0; + double swatUpper = 1.0; + + ternaryRanges(soilLower, soilUpper, sgasLower, sgasUpper, swatLower, swatUpper); + + cvf::String soilRange; + cvf::String sgasRange; + cvf::String swatRange; + + int numberPrecision = 1; + { + QString tmpString = QString::number(soilLower, 'g', numberPrecision) + " - " + QString::number(soilUpper, 'g', numberPrecision); + soilRange = cvfqt::Utils::toString(tmpString); + } + + { + QString tmpString = QString::number(sgasLower, 'g', numberPrecision) + " - " + QString::number(sgasUpper, 'g', numberPrecision); + sgasRange = cvfqt::Utils::toString(tmpString); + } + + { + QString tmpString = QString::number(swatLower, 'g', numberPrecision) + " - " + QString::number(swatUpper, 'g', numberPrecision); + swatRange = cvfqt::Utils::toString(tmpString); + } + + if (!m_legend.isNull()) + { + m_legend->setRangeText(soilRange, sgasRange, swatRange); + } } //-------------------------------------------------------------------------------------------------- From 071abb2c97e0061afd67a6645ef6cde6aa62a49d Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 9 May 2014 07:32:18 +0200 Subject: [PATCH 110/130] Ternary: Improved positioning of SOIL text and range --- .../RivTernarySaturationOverlayItem.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp index cdfcfc5fd5..651297c813 100644 --- a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp +++ b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp @@ -124,8 +124,14 @@ void RivTernarySaturationOverlayItem::render(cvf::OpenGLContext* oglContext, con textDrawer.addText("SWAT", cvf::Vec2f(0.0, 10.0)); textDrawer.addText(m_swatRange, cvf::Vec2f(0.0, 0.0)); - textDrawer.addText("SOIL", cvf::Vec2f(static_cast(size.x() - 40), 10.0)); - textDrawer.addText(m_soilRange, cvf::Vec2f(static_cast(size.x() - 40), 0.0)); + textDrawer.addText("SOIL", cvf::Vec2f(static_cast(size.x() - 25), 10.0)); + + float soilRangePos = static_cast(size.x() - 40); + if (m_soilRange.size() < 6) + { + soilRangePos += 15; + } + textDrawer.addText(m_soilRange, cvf::Vec2f(soilRangePos, 0.0)); textDrawer.addText("SGAS", cvf::Vec2f(static_cast( (size.x() / 2) - 17 ), static_cast(size.y() - 10))); textDrawer.addText(m_sgasRange, cvf::Vec2f(static_cast( (size.x() / 2) - 17 ), static_cast(size.y() - 20))); From dbdd28fcdeebd3f9022619ee15dfdcd391ef6ec1 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 9 May 2014 07:34:27 +0200 Subject: [PATCH 111/130] When no ternary component is present, hide TERNARY result --- ApplicationCode/ProjectDataModel/RimReservoirView.cpp | 3 ++- ApplicationCode/ProjectDataModel/RimResultDefinition.cpp | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp index 6e83c97a77..40350f8c1b 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp @@ -1453,7 +1453,8 @@ void RimReservoirView::updateLegends() viewer()->removeOverlayItem(this->cellResult()->ternaryLegendConfig->legend()); - if (this->cellResult()->isTernarySaturationSelected()) + size_t maxTimeStepCount = results->maxTimeStepCount(); + if (this->cellResult()->isTernarySaturationSelected() && maxTimeStepCount > 1) { RimReservoirCellResultsStorage* gridCellResults = this->cellResult()->currentGridCellResults(); { diff --git a/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp index 7a039c0ae8..110036ffb8 100644 --- a/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp @@ -178,7 +178,12 @@ QList RimResultDefinition::calculateValueOptions(const c optionList.push_front(caf::PdmOptionItemInfo(RimDefines::combinedTransmissibilityResultName(), RimDefines::combinedTransmissibilityResultName())); } - if (m_resultTypeUiField == RimDefines::DYNAMIC_NATIVE) + bool hasAtLeastOneTernaryComponent = false; + if (varList.contains("SOIL")) hasAtLeastOneTernaryComponent = true; + else if (varList.contains("SGAS")) hasAtLeastOneTernaryComponent = true; + else if (varList.contains("SWAT")) hasAtLeastOneTernaryComponent = true; + + if (m_resultTypeUiField == RimDefines::DYNAMIC_NATIVE && hasAtLeastOneTernaryComponent) { optionList.push_front(caf::PdmOptionItemInfo(RimDefines::ternarySaturationResultName(), RimDefines::ternarySaturationResultName())); } From f68aa1908d11708b15514954ba41d23c31a3270b Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 5 Jun 2014 07:34:34 +0200 Subject: [PATCH 112/130] Show help message if positional parameters is present --- ApplicationCode/Application/RiaApplication.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ApplicationCode/Application/RiaApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp index d029af322f..28c6de9612 100644 --- a/ApplicationCode/Application/RiaApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -843,7 +843,12 @@ bool RiaApplication::parseArguments() bool parseOk = progOpt.parse(cvfqt::Utils::toStringVector(arguments)); - if (!parseOk || progOpt.hasOption("help") || progOpt.hasOption("?")) + // If positional parameter functionality is to be supported, the test for existence of positionalParameters must be removed + // This is based on a pull request by @andlaus https://github.com/OPM/ResInsight/pull/162 + if (!parseOk || + progOpt.hasOption("help") || + progOpt.hasOption("?") || + progOpt.positionalParameters().size() > 0) { #if defined(_MSC_VER) && defined(_WIN32) showFormattedTextInMessageBox(m_helpText); From c431e1c1d9a7a43eb493ce6a3d8983b5289209d8 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 9 Jun 2014 12:22:36 +0200 Subject: [PATCH 113/130] Use system Qt if no custom Qt for Octave plugins is specified --- OctavePlugin/CMakeLists.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/OctavePlugin/CMakeLists.txt b/OctavePlugin/CMakeLists.txt index 4ee4dcc138..133000cd7d 100644 --- a/OctavePlugin/CMakeLists.txt +++ b/OctavePlugin/CMakeLists.txt @@ -51,18 +51,26 @@ else() message(WARNING "Failed to find mkoctfile, no Octave plugins will be compiled. Please specify RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE") endif() -find_program(RESINSIGHT_OCTAVE_PLUGIN_QMAKE NAMES qmake-qt4 qmake) + +set(RESINSIGHT_OCTAVE_PLUGIN_QMAKE "" CACHE FILEPATH "Location of custom qmake to be able to use a different Qt when compiling Octave plugins") if(RESINSIGHT_OCTAVE_PLUGIN_QMAKE) get_filename_component(OCTAVE_QMAKE_DIR ${RESINSIGHT_OCTAVE_PLUGIN_QMAKE} PATH) STRING(REPLACE "/bin" "" OCTAVE_QT_ROOT ${OCTAVE_QMAKE_DIR}) + message("Compiling Octave plugins using custom Qt located at ${OCTAVE_QT_ROOT}") + SET(OCTAVE_QT_INCLUDE_DIR ${OCTAVE_QT_ROOT}/include) SET(OCTAVE_QT_QTCORE_INCLUDE_DIR ${OCTAVE_QT_ROOT}/include/QtCore) SET(OCTAVE_QT_QTNETWORK_INCLUDE_DIR ${OCTAVE_QT_ROOT}/include/QtNetwork) SET(OCTAVE_QT_LIBRARY_DIR ${OCTAVE_QT_ROOT}/lib) else() - message(WARNING "Failed to find Qt to be used to compile Octave plugins, no Octave plugins will be compiled. Please specify RESINSIGHT_OCTAVE_PLUGIN_QMAKE") + message("Compiling Octave plugins using system Qt located at ${QT_ROOT}") + + SET(OCTAVE_QT_INCLUDE_DIR ${QT_INCLUDE_DIR}) + SET(OCTAVE_QT_QTCORE_INCLUDE_DIR ${QT_QTCORE_INCLUDE_DIR}) + SET(OCTAVE_QT_QTNETWORK_INCLUDE_DIR ${QT_QTNETWORK_INCLUDE_DIR}) + SET(OCTAVE_QT_LIBRARY_DIR ${QT_LIBRARY_DIR}) endif() From 924a43b4bc48886a1f4e445bd6df97b0222166b2 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 9 Jun 2014 13:12:56 +0200 Subject: [PATCH 114/130] Fix for Octave config with system Qt --- OctavePlugin/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OctavePlugin/CMakeLists.txt b/OctavePlugin/CMakeLists.txt index 133000cd7d..3a017e61de 100644 --- a/OctavePlugin/CMakeLists.txt +++ b/OctavePlugin/CMakeLists.txt @@ -65,7 +65,9 @@ if(RESINSIGHT_OCTAVE_PLUGIN_QMAKE) SET(OCTAVE_QT_QTNETWORK_INCLUDE_DIR ${OCTAVE_QT_ROOT}/include/QtNetwork) SET(OCTAVE_QT_LIBRARY_DIR ${OCTAVE_QT_ROOT}/lib) else() - message("Compiling Octave plugins using system Qt located at ${QT_ROOT}") + set (RESINSIGHT_OCTAVE_PLUGIN_QMAKE ${QT_QMAKE_EXECUTABLE}) + + message("Compiling Octave plugins using system Qt - include path located at ${RESINSIGHT_OCTAVE_PLUGIN_QMAKE}") SET(OCTAVE_QT_INCLUDE_DIR ${QT_INCLUDE_DIR}) SET(OCTAVE_QT_QTCORE_INCLUDE_DIR ${QT_QTCORE_INCLUDE_DIR}) From a37b9f6ea236f634b93c3f340d366bde23deda93 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Wed, 11 Jun 2014 08:42:47 +0200 Subject: [PATCH 115/130] Consolidated reading of double data from input file --- .../RifEclipseInputFileTools.cpp | 106 ++++++++++-------- 1 file changed, 61 insertions(+), 45 deletions(-) diff --git a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp index d2ddac49a8..559b1d84bb 100644 --- a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp @@ -17,15 +17,17 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RifEclipseInputFileTools.h" + #include "RifReaderEclipseOutput.h" #include "RigCaseCellResultsData.h" - #include "RigCaseData.h" + #include "cafProgressInfo.h" -#include #include +#include #include +#include #include #include @@ -34,10 +36,8 @@ #include #include "ecl_grid.h" -#include "well_state.h" #include "util.h" -#include - +#include "well_state.h" QString includeKeyword("INCLUDE"); @@ -46,6 +46,35 @@ QString editKeyword("EDIT"); QString gridKeyword("GRID"); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t findOrCreateResult(const QString& newResultName, RigCaseData* reservoir) +{ + size_t resultIndex = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(newResultName); + if (resultIndex == cvf::UNDEFINED_SIZE_T) + { + resultIndex = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName, false); + } + + return resultIndex; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool readDoubleValues(RigCaseData* reservoir, size_t resultIndex, ecl_kw_type* eclKeyWordData) +{ + if (resultIndex == cvf::UNDEFINED_SIZE_T) return false; + + 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()); +} + + //-------------------------------------------------------------------------------------------------- /// Constructor //-------------------------------------------------------------------------------------------------- @@ -197,9 +226,9 @@ bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigCaseData //-------------------------------------------------------------------------------------------------- /// Read known properties from the input file //-------------------------------------------------------------------------------------------------- -std::map RifEclipseInputFileTools::readProperties(const QString &fileName, RigCaseData *reservoir) +std::map RifEclipseInputFileTools::readProperties(const QString &fileName, RigCaseData* caseData) { - CVF_ASSERT(reservoir); + CVF_ASSERT(caseData); std::set knownKeywordSet; { @@ -231,19 +260,18 @@ std::map RifEclipseInputFileTools::readProperties(const QStri if (knownKeywordSet.count(fileKeywords[i].keyword)) { fseek(gridFilePointer, fileKeywords[i].filePos, SEEK_SET); - ecl_kw_type* eclKeyWordData = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ECL_FLOAT_TYPE); - if (eclKeyWordData) + ecl_kw_type* eclipseKeywordData = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ECL_FLOAT_TYPE); + if (eclipseKeywordData) { - QString newResultName = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->makeResultNameUnique(fileKeywords[i].keyword); - - 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 + QString newResultName = caseData->results(RifReaderInterface::MATRIX_RESULTS)->makeResultNameUnique(fileKeywords[i].keyword); - 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()); + size_t resultIndex = findOrCreateResult(newResultName, caseData); + if (resultIndex != cvf::UNDEFINED_SIZE_T) + { + readDoubleValues(caseData, resultIndex, eclipseKeywordData); + } - ecl_kw_free(eclKeyWordData); + ecl_kw_free(eclipseKeywordData); newResults[newResultName] = fileKeywords[i].keyword; } } @@ -300,30 +328,24 @@ void RifEclipseInputFileTools::findKeywordsOnFile(const QString &fileName, std:: /// Reads the property data requested into the \a reservoir, overwriting any previous /// propeties with the same name. //-------------------------------------------------------------------------------------------------- -bool RifEclipseInputFileTools::readProperty(const QString& fileName, RigCaseData* eclipseCase, const QString& eclipseKeyWord, const QString& resultName) +bool RifEclipseInputFileTools::readProperty(const QString& fileName, RigCaseData* caseData, const QString& eclipseKeyWord, const QString& resultName) { - CVF_ASSERT(eclipseCase); + CVF_ASSERT(caseData); FILE* filePointer = util_fopen(fileName.toLatin1().data(), "r"); if (!filePointer) return false; - ecl_kw_type* eclKeyWordData = ecl_kw_fscanf_alloc_grdecl_dynamic__( filePointer , eclipseKeyWord.toLatin1().data() , false , ECL_FLOAT_TYPE); + ecl_kw_type* eclipseKeywordData = ecl_kw_fscanf_alloc_grdecl_dynamic__( filePointer , eclipseKeyWord.toLatin1().data() , false , ECL_FLOAT_TYPE); bool isOk = false; - if (eclKeyWordData) + if (eclipseKeywordData) { - QString newResultName = resultName; - size_t resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(newResultName); - if (resultIndex == cvf::UNDEFINED_SIZE_T) + size_t resultIndex = findOrCreateResult(resultName, caseData); + if (resultIndex != cvf::UNDEFINED_SIZE_T) { - resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName, false); + isOk = readDoubleValues(caseData, resultIndex, eclipseKeywordData); } - std::vector< std::vector >& newPropertyData = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); - newPropertyData.resize(1); - newPropertyData[0].resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL); - ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data()); - isOk = true; - ecl_kw_free(eclKeyWordData); + ecl_kw_free(eclipseKeywordData); } util_fclose(filePointer); @@ -535,31 +557,25 @@ void RifEclipseInputFileTools::findGridKeywordPositions(const std::vector< RifKe //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifEclipseInputFileTools::readPropertyAtFilePosition(const QString& fileName, RigCaseData* eclipseCase, const QString& eclipseKeyWord, qint64 filePos, const QString& resultName) +bool RifEclipseInputFileTools::readPropertyAtFilePosition(const QString& fileName, RigCaseData* caseData, const QString& eclipseKeyWord, qint64 filePos, const QString& resultName) { - CVF_ASSERT(eclipseCase); + CVF_ASSERT(caseData); FILE* filePointer = util_fopen(fileName.toLatin1().data(), "r"); if (!filePointer) return false; fseek(filePointer, filePos, SEEK_SET); - ecl_kw_type* eclKeyWordData = ecl_kw_fscanf_alloc_current_grdecl__(filePointer, false , ECL_FLOAT_TYPE); + ecl_kw_type* eclipseKeywordData = ecl_kw_fscanf_alloc_current_grdecl__(filePointer, false , ECL_FLOAT_TYPE); bool isOk = false; - if (eclKeyWordData) + if (eclipseKeywordData) { - QString newResultName = resultName; - size_t resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(newResultName); - if (resultIndex == cvf::UNDEFINED_SIZE_T) + size_t resultIndex = findOrCreateResult(resultName, caseData); + if (resultIndex != cvf::UNDEFINED_SIZE_T) { - resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName, false); + isOk = readDoubleValues(caseData, resultIndex, eclipseKeywordData); } - std::vector< std::vector >& newPropertyData = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); - newPropertyData.resize(1); - newPropertyData[0].resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL); - ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data()); - isOk = true; - ecl_kw_free(eclKeyWordData); + ecl_kw_free(eclipseKeywordData); } util_fclose(filePointer); From 7faf950dc7e655879ce954d365ea34945dc7ad23 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Wed, 11 Jun 2014 12:06:15 +0200 Subject: [PATCH 116/130] riGetActiveCellProperty: Fix for input properties Only read values for active cells if we have result values for all cells --- .../RifEclipseInputFileTools.cpp | 40 ++++++++++++++++++- .../RiaPropertyDataCommands.cpp | 36 +++++++++++------ 2 files changed, 63 insertions(+), 13 deletions(-) diff --git a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp index 559b1d84bb..5feeb2908c 100644 --- a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp @@ -62,7 +62,8 @@ size_t findOrCreateResult(const QString& newResultName, RigCaseData* reservoir) //-------------------------------------------------------------------------------------------------- -/// +/// Read all double values from input file. To reduce memory footprint, the alternative method +/// readDoubleValuesForActiveCells() can be used, and will skip all cell values for inactive cells //-------------------------------------------------------------------------------------------------- bool readDoubleValues(RigCaseData* reservoir, size_t resultIndex, ecl_kw_type* eclKeyWordData) { @@ -74,6 +75,43 @@ bool readDoubleValues(RigCaseData* reservoir, size_t resultIndex, ecl_kw_type* e ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data()); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool readDoubleValuesForActiveCells(RigCaseData* reservoir, size_t resultIndex, ecl_kw_type* eclKeyWordData) +{ + if (resultIndex == cvf::UNDEFINED_SIZE_T) return false; + + std::vector< std::vector >& newPropertyData = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); + newPropertyData.push_back(std::vector()); + + RigActiveCellInfo* activeCellInfo = reservoir->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); + if (activeCellInfo->globalCellCount() > 0 && activeCellInfo->globalCellCount() != activeCellInfo->globalActiveCellCount()) + { + std::vector valuesAllCells; + valuesAllCells.resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL); + ecl_kw_get_data_as_double(eclKeyWordData, valuesAllCells.data()); + + newPropertyData[0].resize(activeCellInfo->globalActiveCellCount(), HUGE_VAL); + std::vector& valuesActiveCells = newPropertyData[0]; + + size_t acIdx = 0; + for (size_t gcIdx = 0; gcIdx < activeCellInfo->globalCellCount(); gcIdx++) + { + size_t activeCellResultIndex = activeCellInfo->cellResultIndex(gcIdx); + if (activeCellResultIndex != cvf::UNDEFINED_SIZE_T) + { + valuesActiveCells[activeCellResultIndex] = valuesAllCells[gcIdx]; + } + } + } + else + { + newPropertyData[0].resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL); + ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data()); + } +} + //-------------------------------------------------------------------------------------------------- /// Constructor diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index 1d1b1b5420..fa5fc419fd 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -153,30 +153,42 @@ class RiaGetActiveCellProperty: public RiaSocketCommand size_t globalCellCount = activeInfo->globalCellCount(); for (size_t tIdx = 0; tIdx < requestedTimesteps.size(); ++tIdx) { + std::vector& doubleValues = scalarResultFrames->at(requestedTimesteps[tIdx]); for (size_t gcIdx = 0; gcIdx < globalCellCount; ++gcIdx) { size_t resultIdx = activeInfo->cellResultIndex(gcIdx); - if (resultIdx != cvf::UNDEFINED_SIZE_T) + if (resultIdx == cvf::UNDEFINED_SIZE_T) continue; + + if (resultIdx < doubleValues.size()) { - if (resultIdx < scalarResultFrames->at(requestedTimesteps[tIdx]).size()) + if (doubleValues.size() == activeInfo->globalCellCount()) { - values[valueIndex] = scalarResultFrames->at(requestedTimesteps[tIdx])[resultIdx]; + // When reading data from input text files, result data is read for all grid cells + // Read out values from data vector using global cell index instead of active cell result index + // When data is written back to ResInsight using RiaSetActiveCellProperty, the resulting + // data vector will have activeCellCount data values, which is potentially smaller + // than total number of cells + values[valueIndex] = doubleValues[gcIdx]; } else { - values[valueIndex] = HUGE_VAL; + values[valueIndex] = doubleValues[resultIdx]; } + } + else + { + values[valueIndex] = HUGE_VAL; + } - valueIndex++; - if (valueIndex >= valueCount) + valueIndex++; + if (valueIndex >= valueCount) + { + if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double))) { - if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double))) - { - return false; - } - - valueIndex = 0; + return false; } + + valueIndex = 0; } } } From a29a388df212561a5d27780422eb58aee835ac93 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 12 Jun 2014 08:00:28 +0200 Subject: [PATCH 117/130] Fixed issue when combining static and dynamic filters Time step index was set to 0 for static results. This was also done for all other filters, which caused dynamic filters to always evaluate time step 0 --- .../ModelVisualization/RivReservoirViewPartMgr.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp index e0dbb2bd02..3f78c6d111 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp @@ -714,10 +714,12 @@ void RivReservoirViewPartMgr::computePropertyVisibility(cvf::UByteArray* cellVis size_t scalarResultIndex = (*pfIt)->resultDefinition->gridScalarIndex(); + size_t adjustedTimeStepIndex = timeStepIndex; + // Set time step to zero for static results if ((*pfIt)->resultDefinition()->hasStaticResult()) { - timeStepIndex = 0; + adjustedTimeStepIndex = 0; } const RimCellFilter::FilterModeType filterType = (*pfIt)->filterMode(); @@ -725,7 +727,7 @@ void RivReservoirViewPartMgr::computePropertyVisibility(cvf::UByteArray* cellVis RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel((*pfIt)->resultDefinition()->porosityModel()); RigCaseData* eclipseCase = propFilterColl->reservoirView()->eclipseCase()->reservoirData(); - cvf::ref dataAccessObject = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, scalarResultIndex); + cvf::ref dataAccessObject = eclipseCase->dataAccessObject(grid, porosityModel, adjustedTimeStepIndex, scalarResultIndex); CVF_ASSERT(dataAccessObject.notNull()); //#pragma omp parallel for schedule(dynamic) From 6a20f16de121d6461289819f6f45af6a8542183b Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 13 Jun 2014 08:12:45 +0200 Subject: [PATCH 118/130] Legend config: Do not show two configs when loading new case --- .../ProjectDataModel/RimReservoirView.cpp | 2 +- .../ProjectDataModel/RimResultDefinition.h | 2 +- .../ProjectDataModel/RimResultSlot.cpp | 25 +++++++++++++++---- .../ProjectDataModel/RimResultSlot.h | 4 ++- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp index 40350f8c1b..ddc3cfdc02 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp @@ -174,8 +174,8 @@ RimReservoirView::RimReservoirView() this->cellResult()->setReservoirView(this); - this->cellResult()->legendConfig()->setReservoirView(this); this->cellResult()->legendConfig()->setPosition(cvf::Vec2ui(10, 120)); + this->cellEdgeResult()->setReservoirView(this); this->cellEdgeResult()->legendConfig()->setReservoirView(this); this->cellEdgeResult()->legendConfig()->setPosition(cvf::Vec2ui(10, 320)); diff --git a/ApplicationCode/ProjectDataModel/RimResultDefinition.h b/ApplicationCode/ProjectDataModel/RimResultDefinition.h index dbe558eac2..3e7e463f7d 100644 --- a/ApplicationCode/ProjectDataModel/RimResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimResultDefinition.h @@ -47,7 +47,7 @@ class RimResultDefinition : public caf::PdmObject RimDefines::PorosityModelType porosityModel() const { return m_porosityModel(); } void setPorosityModel(RimDefines::PorosityModelType val); QString resultVariable() const { return m_resultVariable(); } - void setResultVariable(const QString& val); + virtual void setResultVariable(const QString& val); void setPorosityModelUiFieldHidden(bool hide); void loadResult(); diff --git a/ApplicationCode/ProjectDataModel/RimResultSlot.cpp b/ApplicationCode/ProjectDataModel/RimResultSlot.cpp index 5e4e6452b0..38108eaf5f 100644 --- a/ApplicationCode/ProjectDataModel/RimResultSlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultSlot.cpp @@ -35,14 +35,18 @@ RimResultSlot::RimResultSlot() CAF_PDM_InitObject("Result Slot", "", "", ""); CAF_PDM_InitFieldNoDefault(&legendConfig, "LegendDefinition", "Legend Definition", "", "", ""); + this->legendConfig = new RimLegendConfig(); + this->legendConfig.setUiHidden(true); + this->legendConfig.setUiChildrenHidden(true); + CAF_PDM_InitFieldNoDefault(&m_legendConfigData, "ResultVarLegendDefinitionList", "", "", "", ""); m_legendConfigData.setUiHidden(true); m_legendConfigData.setUiChildrenHidden(true); CAF_PDM_InitFieldNoDefault(&ternaryLegendConfig, "TernaryLegendDefinition", "Ternary Legend Definition", "", "", ""); - ternaryLegendConfig = new RimTernaryLegendConfig(); - - legendConfig = new RimLegendConfig(); + this->ternaryLegendConfig = new RimTernaryLegendConfig(); + this->ternaryLegendConfig.setUiHidden(true); + this->ternaryLegendConfig.setUiChildrenHidden(true); } //-------------------------------------------------------------------------------------------------- @@ -73,6 +77,8 @@ void RimResultSlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, co { if (m_reservoirView) m_reservoirView->animationMode = true; } + + RiuMainWindow::instance()->uiPdmModel()->updateUiSubTree(this); } if (m_reservoirView) m_reservoirView->createDisplayModelAndRedraw(); @@ -128,7 +134,6 @@ void RimResultSlot::changeLegendConfig(QString resultVarNameOfNewLegend) this->legendConfig.setUiChildrenHidden(false); } - RiuMainWindow::instance()->uiPdmModel()->updateUiSubTree(this); } //-------------------------------------------------------------------------------------------------- @@ -159,6 +164,16 @@ void RimResultSlot::setReservoirView(RimReservoirView* ownerReservoirView) (*it)->setReservoirView(ownerReservoirView); } - if (ternaryLegendConfig) ternaryLegendConfig->setReservoirView(ownerReservoirView); + this->ternaryLegendConfig()->setReservoirView(ownerReservoirView); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimResultSlot::setResultVariable(const QString& val) +{ + RimResultDefinition::setResultVariable(val); + + this->changeLegendConfig(val); } diff --git a/ApplicationCode/ProjectDataModel/RimResultSlot.h b/ApplicationCode/ProjectDataModel/RimResultSlot.h index a5b9ec909d..afa92bb3a3 100644 --- a/ApplicationCode/ProjectDataModel/RimResultSlot.h +++ b/ApplicationCode/ProjectDataModel/RimResultSlot.h @@ -43,7 +43,9 @@ class RimResultSlot : public RimResultDefinition caf::PdmField ternaryLegendConfig; // Overridden methods - virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + virtual void setResultVariable(const QString& resultName); + protected: virtual void initAfterRead(); From 7846bb1ac61817fb836d09e4ab6c95bdddd487cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Fri, 20 Jun 2014 12:41:16 +0200 Subject: [PATCH 119/130] Fixed bug in Combined Trans result. Wrong neighbour was used, so the results was actually completely wrong in any sence for the negative faces. --- ApplicationCode/ModelVisualization/RivGridPartMgr.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index c209a4d578..ddf67713c6 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -567,7 +567,7 @@ void RivTransmissibilityColorMapper::updateCombinedTransmissibilityTextureCoordi size_t i, j, k, neighborGridCellIdx; grid->ijkFromCellIndex(quadsToGridCells[idx], &i, &j, &k); - if(grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::POS_I, &neighborGridCellIdx)) + if(grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::NEG_I, &neighborGridCellIdx)) { cellScalarValue = dataAccessObjectTranX->cellScalar(neighborGridCellIdx); } @@ -581,7 +581,7 @@ void RivTransmissibilityColorMapper::updateCombinedTransmissibilityTextureCoordi size_t i, j, k, neighborGridCellIdx; grid->ijkFromCellIndex(quadsToGridCells[idx], &i, &j, &k); - if(grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::POS_J, &neighborGridCellIdx)) + if(grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::NEG_J, &neighborGridCellIdx)) { cellScalarValue = dataAccessObjectTranY->cellScalar(neighborGridCellIdx); } @@ -595,7 +595,7 @@ void RivTransmissibilityColorMapper::updateCombinedTransmissibilityTextureCoordi size_t i, j, k, neighborGridCellIdx; grid->ijkFromCellIndex(quadsToGridCells[idx], &i, &j, &k); - if(grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::POS_K, &neighborGridCellIdx)) + if(grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::NEG_K, &neighborGridCellIdx)) { cellScalarValue = dataAccessObjectTranZ->cellScalar(neighborGridCellIdx); } From e1c55e4452f87c145d9b5729114c1942219c4097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Fri, 20 Jun 2014 14:05:28 +0200 Subject: [PATCH 120/130] Comb Trans: Fixed max/min and close to zero calc --- .../RigCaseCellResultsData.cpp | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp index 36516365d0..ea168688b6 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp @@ -122,9 +122,20 @@ void RigCaseCellResultsData::minMaxCellScalarValues(size_t scalarResultIndex, si size_t tranX, tranY, tranZ; if (!findTransmissibilityResults(tranX, tranY, tranZ)) return; - minMaxCellScalarValues(tranX, timeStepIndex, min, max); - minMaxCellScalarValues(tranY, timeStepIndex, min, max); - minMaxCellScalarValues(tranZ, timeStepIndex, min, max); + double tranMin; + double tranMax; + + minMaxCellScalarValues(tranX, timeStepIndex, tranMin, tranMax); + min = CVF_MIN(tranMin, min); + max = CVF_MAX(tranMax, max); + + minMaxCellScalarValues(tranY, timeStepIndex, tranMin, tranMax); + min = CVF_MIN(tranMin, min); + max = CVF_MAX(tranMax, max); + + minMaxCellScalarValues(tranZ, timeStepIndex, tranMin, tranMax); + min = CVF_MIN(tranMin, min); + max = CVF_MAX(tranMax, max); return; } @@ -738,9 +749,16 @@ void RigCaseCellResultsData::posNegClosestToZero(size_t scalarResultIndex, size_ size_t tranX, tranY, tranZ; if (findTransmissibilityResults(tranX, tranY, tranZ)) { - posNegClosestToZero(tranX, timeStepIndex, pos, neg); - posNegClosestToZero(tranY, timeStepIndex, pos, neg); - posNegClosestToZero(tranZ, timeStepIndex, pos, neg); + double traPos, traNeg; + posNegClosestToZero(tranX, timeStepIndex, traPos, traNeg); + if ( 0 < traPos && traPos < pos ) pos = traPos; + if ( neg < traNeg && traNeg < 0 ) neg = traNeg; + posNegClosestToZero(tranY, timeStepIndex, traPos, traNeg); + if ( 0 < traPos && traPos < pos ) pos = traPos; + if ( neg < traNeg && traNeg < 0 ) neg = traNeg; + posNegClosestToZero(tranZ, timeStepIndex, traPos, traNeg); + if ( 0 < traPos && traPos < pos ) pos = traPos; + if ( neg < traNeg && traNeg < 0 ) neg = traNeg; } return; From f5b0e03211f748311941421158c08fc1ee11e9c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Mon, 30 Jun 2014 11:10:35 +0200 Subject: [PATCH 121/130] Fix of crash: Compute SOIL for Fracture Results https://github.com/OPM/ResInsight/issues/179 --- .../ProjectDataModel/RimReservoirView.cpp | 41 +++++++++++++------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp index ddc3cfdc02..8ce24dd443 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp @@ -932,10 +932,16 @@ void RimReservoirView::loadDataAndUpdate() RiaApplication* app = RiaApplication::instance(); if (app->preferences()->autocomputeSOIL) { - RimReservoirCellResultsStorage* results = currentGridCellResults(); - CVF_ASSERT(results); - results->loadOrComputeSOIL(); - results->createCombinedTransmissibilityResults(); + { + RimReservoirCellResultsStorage* results = m_reservoir->results(RifReaderInterface::MATRIX_RESULTS); + results->loadOrComputeSOIL(); + results->createCombinedTransmissibilityResults(); + } + { + RimReservoirCellResultsStorage* results = m_reservoir->results(RifReaderInterface::FRACTURE_RESULTS); + results->loadOrComputeSOIL(); + results->createCombinedTransmissibilityResults(); + } } } } @@ -1464,10 +1470,13 @@ void RimReservoirView::updateLegends() double localMax = 1.0; size_t scalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); - results->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax); - results->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax); + if (scalarSetIndex != cvf::UNDEFINED_SIZE_T) + { + results->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax); + results->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax); - this->cellResult()->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SOIL_IDX, globalMin, globalMax, localMin, localMax); + this->cellResult()->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SOIL_IDX, globalMin, globalMax, localMin, localMax); + } } { @@ -1477,10 +1486,13 @@ void RimReservoirView::updateLegends() double localMax = 1.0; size_t scalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); - results->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax); - results->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax); + if (scalarSetIndex != cvf::UNDEFINED_SIZE_T) + { + results->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax); + results->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax); - this->cellResult()->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SGAS_IDX, globalMin, globalMax, localMin, localMax); + this->cellResult()->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SGAS_IDX, globalMin, globalMax, localMin, localMax); + } } { @@ -1490,10 +1502,13 @@ void RimReservoirView::updateLegends() double localMax = 1.0; size_t scalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); - results->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax); - results->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax); + if (scalarSetIndex != cvf::UNDEFINED_SIZE_T) + { + results->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax); + results->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax); - this->cellResult()->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SWAT_IDX, globalMin, globalMax, localMin, localMax); + this->cellResult()->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SWAT_IDX, globalMin, globalMax, localMin, localMax); + } } if (this->cellResult()->ternaryLegendConfig->legend()) From 076601e0e5405edefb3e5a2513e6cce37f6a45e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Mon, 30 Jun 2014 11:20:27 +0200 Subject: [PATCH 122/130] Fault Results: Fix of crash with None as selected result Discovered during regtest --- .../ModelVisualization/RivFaultPartMgr.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp b/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp index 33e3474d97..138c280986 100644 --- a/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp @@ -140,10 +140,12 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* } else { - if (dataAccessObject.notNull()) + if (dataAccessObject.isNull()) { - m_nativeFaultGenerator->textureCoordinates(m_nativeFaultFacesTextureCoords.p(), dataAccessObject.p(), mapper); + return; } + m_nativeFaultGenerator->textureCoordinates(m_nativeFaultFacesTextureCoords.p(), dataAccessObject.p(), mapper); + } if (m_opacityLevel < 1.0f ) @@ -214,10 +216,12 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* } else { - if (dataAccessObject.notNull()) + if (dataAccessObject.isNull()) { - m_oppositeFaultGenerator->textureCoordinates(m_oppositeFaultFacesTextureCoords.p(), dataAccessObject.p(), mapper); + return; } + + m_oppositeFaultGenerator->textureCoordinates(m_oppositeFaultFacesTextureCoords.p(), dataAccessObject.p(), mapper); } if (m_opacityLevel < 1.0f ) From 82e97da5536227ce89bc193d6f38dbebe3f5a6ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Mon, 30 Jun 2014 12:00:41 +0200 Subject: [PATCH 123/130] Fixed Octave Hang after large dataset writes https://github.com/OPM/ResInsight/issues/192 --- OctavePlugin/riSetActiveCellProperty.cpp | 4 +++- OctavePlugin/riSetGridProperty.cpp | 2 +- OctavePlugin/riSettings.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/OctavePlugin/riSetActiveCellProperty.cpp b/OctavePlugin/riSetActiveCellProperty.cpp index b4981a70cc..a079ccd0da 100644 --- a/OctavePlugin/riSetActiveCellProperty.cpp +++ b/OctavePlugin/riSetActiveCellProperty.cpp @@ -78,10 +78,12 @@ void setEclipseProperty(const Matrix& propertyFrames, const QString &hostName, q while(socket.bytesToWrite() && socket.state() == QAbstractSocket::ConnectedState) { // octave_stdout << "Bytes to write: " << socket.bytesToWrite() << std::endl; - socket.waitForBytesWritten(riOctavePlugin::longTimeOutMilliSecs); + socket.waitForBytesWritten(riOctavePlugin::shortTimeOutMilliSecs); OCTAVE_QUIT; } + //octave_stdout << " Socket write completed" << std::endl; + if (socket.bytesToWrite() && socket.state() != QAbstractSocket::ConnectedState) { error("riSetActiveCellProperty : ResInsight refused to accept the data. Maybe the dimensions or porosity model is wrong"); diff --git a/OctavePlugin/riSetGridProperty.cpp b/OctavePlugin/riSetGridProperty.cpp index 8598d4b32e..3ef34adda4 100644 --- a/OctavePlugin/riSetGridProperty.cpp +++ b/OctavePlugin/riSetGridProperty.cpp @@ -102,7 +102,7 @@ void setEclipseProperty(const NDArray& propertyFrames, const QString &hostName, while(socket.bytesToWrite() && socket.state() == QAbstractSocket::ConnectedState) { // octave_stdout << "Bytes to write: " << socket.bytesToWrite() << std::endl << std::flush; - socket.waitForBytesWritten(riOctavePlugin::longTimeOutMilliSecs); + socket.waitForBytesWritten(riOctavePlugin::shortTimeOutMilliSecs); OCTAVE_QUIT; } diff --git a/OctavePlugin/riSettings.h b/OctavePlugin/riSettings.h index 5765244a6d..63ad778b37 100644 --- a/OctavePlugin/riSettings.h +++ b/OctavePlugin/riSettings.h @@ -21,7 +21,7 @@ namespace riOctavePlugin { const int connectTimeOutMilliSecs = 5000; - const int shortTimeOutMilliSecs = 5000; + const int shortTimeOutMilliSecs = 1000; const int longTimeOutMilliSecs = 6000000; const int socketMaxByteCount = 100000; From 2a61073b26018be091e97671b8d06b5a5be9f4f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Tue, 1 Jul 2014 14:28:06 +0200 Subject: [PATCH 124/130] Fixed missing Well cell transparency on faults --- .../ModelVisualization/RivFaultPartMgr.cpp | 25 ++++++++++++------- .../ModelVisualization/RivFaultPartMgr.h | 1 + .../RivReservoirFaultsPartMgr.cpp | 11 ++++++++ .../RivReservoirFaultsPartMgr.h | 1 + .../RivReservoirPartMgr.cpp | 1 + 5 files changed, 30 insertions(+), 9 deletions(-) diff --git a/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp b/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp index 138c280986..e2df00d265 100644 --- a/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp @@ -281,15 +281,15 @@ void RivFaultPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimResultS } +const int priFaultGeo = 1; +const int priNncGeo = 2; +const int priMesh = 3; //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivFaultPartMgr::generatePartGeometry() { - const int priFaultGeo = 1; - const int priNncGeo = 2; - const int priMesh = 3; bool useBufferObjects = true; // Surface geometry @@ -476,13 +476,20 @@ void RivFaultPartMgr::updatePartEffect() if (m_opacityLevel < 1.0f) { - // Must be fixed since currently fault drawing relies on internal priorities of the parts - CVF_FAIL_MSG("Not implemented"); - // Set priority to make sure this transparent geometry are rendered last - if (m_nativeFaultFaces.notNull()) m_nativeFaultFaces->setPriority(100); - if (m_oppositeFaultFaces.notNull()) m_oppositeFaultFaces->setPriority(100); - if (m_NNCFaces.notNull()) m_NNCFaces->setPriority(100); + if (m_nativeFaultFaces.notNull()) m_nativeFaultFaces->setPriority(100 + priFaultGeo); + if (m_oppositeFaultFaces.notNull()) m_oppositeFaultFaces->setPriority(100 + priFaultGeo); + if (m_NNCFaces.notNull()) m_NNCFaces->setPriority(100 + priNncGeo); + + if (m_nativeFaultGridLines.notNull()) + { + m_nativeFaultGridLines->setPriority(100 + priMesh); + } + + if (m_oppositeFaultGridLines.notNull()) + { + m_oppositeFaultGridLines->setPriority(100 + priMesh); + } } } diff --git a/ApplicationCode/ModelVisualization/RivFaultPartMgr.h b/ApplicationCode/ModelVisualization/RivFaultPartMgr.h index 139c6b57dd..d4a01e8736 100644 --- a/ApplicationCode/ModelVisualization/RivFaultPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivFaultPartMgr.h @@ -53,6 +53,7 @@ class RivFaultPartMgr : public cvf::Object void setCellVisibility(cvf::UByteArray* cellVisibilities); void applySingleColorEffect(); + void setOpacityLevel(float opacity) { m_opacityLevel = opacity; } void updateCellResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot); void updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot); diff --git a/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp index ea0977e82c..edf8642a9c 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp @@ -233,3 +233,14 @@ void RivReservoirFaultsPartMgr::setFaultForceVisibility(bool forceVisibility) m_forceVisibility = forceVisibility; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivReservoirFaultsPartMgr::setOpacityLevel(float opacity) +{ + for (size_t i = 0; i < m_faultParts.size(); i++) + { + m_faultParts[i]->setOpacityLevel(opacity); + } +} + diff --git a/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.h index 10ea6e943f..105b20468f 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.h @@ -46,6 +46,7 @@ class RivReservoirFaultsPartMgr : public cvf::Object void setCellVisibility(cvf::UByteArray* cellVisibilities); void setFaultForceVisibility(bool isFilterGenerated); + void setOpacityLevel(float opacity); void applySingleColorEffect(); void updateColors(size_t timeStepIndex, RimResultSlot* cellResultSlot); void updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot, diff --git a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp index 3bce9cdfed..88a70ef1d2 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp @@ -98,6 +98,7 @@ void RivReservoirPartMgr::updateCellColor(cvf::Color4f color) if (m_faultsPartMgr.notNull()) { + m_faultsPartMgr->setOpacityLevel(color.a()); m_faultsPartMgr->applySingleColorEffect(); } } From 8f798cd78bd552cda28277063d456b3570d9672c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Tue, 1 Jul 2014 14:28:49 +0200 Subject: [PATCH 125/130] Info Box: Shortened Fault result text --- .../ProjectDataModel/Rim3dOverlayInfoConfig.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp index 8e49426dae..347895c6a1 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp @@ -170,20 +170,20 @@ void Rim3dOverlayInfoConfig::update3DInfo() { if (m_reservoirView->faultCollection()->faultResult() == RimFaultCollection::FAULT_BACK_FACE_CULLING) { - faultMapping = "Show values from cells behind fault"; + faultMapping = "Cells behind fault"; } else if (m_reservoirView->faultCollection()->faultResult() == RimFaultCollection::FAULT_FRONT_FACE_CULLING) { - faultMapping = "Show values from cells in front of fault"; + faultMapping = "Cells in front of fault"; } else { - faultMapping = "Show values from cells in front and behind fault"; + faultMapping = "Cells in front and behind fault"; } } else { - faultMapping = "Show values from cells in front and behind fault"; + faultMapping = "Cells in front and behind fault"; } infoText += QString("Fault results: %1
").arg(faultMapping); From 2d9dd7c75bad02ac92c21ecab00a5c20b05283a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Tue, 1 Jul 2014 14:29:31 +0200 Subject: [PATCH 126/130] Turned On results on Faults by default --- ApplicationCode/ProjectDataModel/RimFaultCollection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp b/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp index 4400f18536..062719de3c 100644 --- a/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp @@ -73,7 +73,7 @@ RimFaultCollection::RimFaultCollection() CAF_PDM_InitField(&showFaultFaces, "ShowFaultFaces", true, "Show defined faces", "", "", ""); CAF_PDM_InitField(&showOppositeFaultFaces, "ShowOppositeFaultFaces", true, "Show opposite faces", "", "", ""); CAF_PDM_InitField(&showNNCs, "ShowNNCs", false, "Show NNCs", "", "", ""); - CAF_PDM_InitField(&showResultsOnFaults, "ShowResultsOnFaults", false, "Show results on faults", "", "", ""); + CAF_PDM_InitField(&showResultsOnFaults, "ShowResultsOnFaults", true, "Show results on faults", "", "", ""); CAF_PDM_InitField(&showFaultsOutsideFilters,"ShowFaultsOutsideFilters", true, "Show faults outside filters", "", "", ""); CAF_PDM_InitField(&faultResult, "FaultFaceCulling", caf::AppEnum(RimFaultCollection::FAULT_BACK_FACE_CULLING), "Dynamic Face Selection", "", "", ""); From c5fa014a5ef091d6161b9ab18ac7a5c50b5be87e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Tue, 1 Jul 2014 15:13:38 +0200 Subject: [PATCH 127/130] Upped to 1.2.0 --- ResInsightVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ResInsightVersion.cmake b/ResInsightVersion.cmake index 4d253b33dc..69e4286f37 100644 --- a/ResInsightVersion.cmake +++ b/ResInsightVersion.cmake @@ -1,6 +1,6 @@ set(CMAKE_MAJOR_VERSION 1) -set(CMAKE_MINOR_VERSION 1) +set(CMAKE_MINOR_VERSION 2) set(CMAKE_PATCH_VERSION 0) set(PRODUCTVER ${CMAKE_MAJOR_VERSION},${CMAKE_MINOR_VERSION},0,${CMAKE_PATCH_VERSION}) From 90f83e3139279d860577a8866eea1ecae7911d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Wed, 2 Jul 2014 10:24:52 +0200 Subject: [PATCH 128/130] Updated doc on Faults, added doc for TRANXYZ and upped to 1.2 --- Documentation/UsersGuide/Faults.md | 82 +++++++++++++++++----- Documentation/UsersGuide/ReservoirViews.md | 5 ++ Documentation/UsersGuide/UsersGuide.md | 2 +- 3 files changed, 69 insertions(+), 20 deletions(-) diff --git a/Documentation/UsersGuide/Faults.md b/Documentation/UsersGuide/Faults.md index 7c19393aa1..5ce0bc92f7 100644 --- a/Documentation/UsersGuide/Faults.md +++ b/Documentation/UsersGuide/Faults.md @@ -3,40 +3,84 @@ ----- ## Faults -ResInsight can import faults from `*.DATA` files, and is available in the ![](images/draw_style_faults_24x24.png) **Faults** item in the **Project Tree**. The imported faults are ordered in ascending order based on name. +ResInsight will detect all the cell faces with no geometrically matching neighbors, and display them as *Faults*. +This means that the are drawn in special ways, and that their visual appearance can be controlled separately from the rest of the grid. -As import of faults can be time consuming, reading of faults can be disabled from **Preferences -> Read fault data** +### Fault Names and NNC -A fault is defined as a set of cell faces. When clicking on a fault, the fault name is displayed in **Result Info**. Results can be mapped onto a fault, and **Dynamic Face Selection** controls the cell result mapping onto faults. Faults are given a color on import, and this color can be controlled by activating the fault and select **Fault color**. +#### Import of Fault info from `*.DATA`-files +If enabled, ResInsight will also import fault information from the `*.DATA` files and use this information to group the detected faces into named items which is available in the ![](images/draw_style_faults_24x24.png) **Faults** item in the **Project Tree**. The imported faults are ordered in ascending order based on their name. -When clicking on a NNC, the relevant data for this NNC is displayed in the **Result Info**. The static result **TRANSXYZ** can be mapped onto NNC geometry. +> +***Note:*** As import of faults can be time consuming, reading of faults can be disabled from **Preferences -> Read fault data** -ResInsight will detect all cell faces with no matching neighbor. All detected cell faces are compared to faults imported from disk, and if no fault face is defined for a cell face, the cell face is added to a fault called **Undefined grid faults**. +#### Undefined grid faults +All the detected cell faces are compared to the faults imported from the `*.DATA` file in order to group them. If a particular face is *not* found among the fault faces defined in the `*.DATA` file or it's opposite face, the cell face is added to a fault called **Undefined grid faults**. This particular Fault will always be present, even if reading of the `*.DATA` file is disabled. -### Toolbar control +#### Fault color + +Each named Fault is given a color on import. This color can be controlled by selecting the fault and edit its **Fault color** in the **Property Editor.** + +#### NNC visualization +ResInsight will read Non Neighbor Connections from the Eclipse output file (`*.INIT`), and create explicit visualizations of those witch have a common surface area. These NNC's are then sorted onto the Fault's and their visibility is controlled from the **Property Editor** of the **Faults** Item in the **Project Tree**. + +The color of the NNC faces are set to be a bit lighter than their corresponding named fault, and can not be controlled directly. + +Currently the only result property that is mapped onto the NNC is the static TRANSXYZ property which displays the transmissibility associated to each face. + +### Picking info + +When clicking on a cell face that is member of a fault, the fault name is displayed in the **Result Info** window, along with cell, and result property info. + +When clicking on a NNC, the relevant data for this NNC is displayed. + +### Fault visualization options + + +#### Toolbar control Visualization mode and mesh lines can be controlled from the toolbar. -- ![](images/draw_style_faults_24x24.png) Toggle button to control faults only visualization mode -- ![](images/draw_style_surface_24x24.png) Shows surface visualization -- ![](images/draw_style_surface_w_fault_mesh_24x24.png) Shows mesh lines on faults +- ![](images/draw_style_faults_24x24.png) **Faults-Only** visualization mode. +
When turned on, this option hides all the grid cells, and shows only the fault faces in the reservoir limited by the applied range and property filters. (Unless **Show faults outside filters** are turned on. See below.) +- ![](images/draw_style_surface_24x24.png) Turns faces on and mesh off +- ![](images/draw_style_surface_w_fault_mesh_24x24.png) Turns on all faces, and shows meshlines on faults only. +
This is a useful method to highlight the faults in your reservoir, because the faults stands out with black outlining. - ![](images/draw_style_faults_label_24x24.png) Shows labels for faults -### Common Fault Options -By clicking the ![](images/draw_style_faults_24x24.png) **Faults** item in the **Project Tree**, the following options are displayed: +#### Common Fault Options +By clicking the ![](images/draw_style_faults_24x24.png) **Faults** item in the **Project Tree**, the following options common to all the faults are displayed: ![](images/FaultProperties.png) - -- **Show labels**: Displays one label per fault with fault name +##### Fault labels +- **Show labels**: Displays one label per fault with the name defined in the `*.DATA`-file - **Label color**: Defines the label color -- **Show faults outside filters**: Default behavior is to hide faults outside filters. Turning this option on, will display faults outside filter region. -- **Show results on faults**: Map currently selected result onto fault. **Dynamic Face Selection** controls which cell results to map onto faults. -- **Show NNCs**: Displays non neighborhood connections (see details below) +##### Fault options +- **Show faults outside filters**: Turning this option on, will display faults outside the filter region, making the fault visualization completely ignore the Range and Property filters in action. +- **Show results on faults**: This toggle controls whether to show the selected result property on the faults or not. This should normally be left on. +- **Show NNCs**: Toggles whether to display the Non Neighbor Connections, or not. + +##### Fault Face Visibility +This group of options controls the visibility of the fault faces. Since they work together, and in some cases are overridden by the system, they can be a bit confusing. + +First of all. These options are only available in **Faults-only** visualization mode. ( See *Toolbar Control* above) When not in **Faults-Only** mode, ResInsight overrides the options, and the controls are inactive. + +Secondly: The option you would normally want to adjust is **Dynamic Face Selection** (See below). + +- **Show defined faces**: Displays the fault cell faces that are defined on the Eclipse input file (`*.DATA`) +- **Show opposite faces**: Displays the opposite fault cell faces from what is defined on the input file, based on IJK neighbors. +
*These two options should normally be left **On***.
They are useful when investigating the exact faults information provided on the `*.DATA` file. +
If you need to use them, it is normally wise to set the **Dynamic Face Selection** to "Show Both" + +######Dynamic Face Selection: + +At one particular position on a fault there are usually two cells competing for your attention: The cell closer to you as the viewer, or the one further from you. When showing results, this becomes important because these two cell faces have different result property values, and thus color. + +This option controls which of the two cell faces you actually can see: The one behind the fault, or the one in front of the fault. There is also an option of showing both, which will give you an undefined mixture, making it hard to be certain what you see. + +This means that ResInsight turns on or off the faces based on your view position and this option to make sure that you always see the faces (and thus the result property) you request. -- **Show defined faces**: Displays the defined fault cell faces -- **Show opposite faces**: Displays the opposite fault cell faces based on IJK neighbor data -- **Dynamic Face Selection**: Controls mapping of cell results onto a fault, either from cell in front of fault, from cell behind fault or both. ------ [ Contents ](UsersGuide.md#contents) diff --git a/Documentation/UsersGuide/ReservoirViews.md b/Documentation/UsersGuide/ReservoirViews.md index a6fde28cae..2a9df5430b 100644 --- a/Documentation/UsersGuide/ReservoirViews.md +++ b/Documentation/UsersGuide/ReservoirViews.md @@ -13,6 +13,11 @@ Below is a description of the most important View settings and their properties. The **Cell Result** item defines which Eclipse property the 3D View uses for the main cell color. The property can be chosen in the property panel of the **Cell Result** item. The mapping between cell values and color is defined by the **Legend Definition** ![](images/Legend.png) along with some appearance settings on the Legend itself. (Number format etc.) +#### TRANSXYZ +Normally the Cell Result setting gives one cell color based on the legend and the selected Result Property. This is *not* the case for the special static TRANXYZ property. This property gives each face the correct color based on the TRANS value that is associated with that particular face. + +The Positive I-face of the cell gets the cell TRANX value, while the J-face gets the TRANY-value etc. The negative faces, however, get the value from the neighbor cell in that direction. The negative I-face gets the TRANX value of the IJK-neighbor in negative I direction, and so on for the -J and -K faces. + ### Cell Edge Results ![](images/EdgeResult_1.png) The **Cell Edge Result** visualization mode is one of ResInsight's special features. Its main use is to show the MULT(X, Y, Z) properties at the same time. diff --git a/Documentation/UsersGuide/UsersGuide.md b/Documentation/UsersGuide/UsersGuide.md index 746d2e9097..33c21440f4 100644 --- a/Documentation/UsersGuide/UsersGuide.md +++ b/Documentation/UsersGuide/UsersGuide.md @@ -1,4 +1,4 @@ -# ![](images/AppLogo48x48.png) ResInsight 1.0 Users Guide +# ![](images/AppLogo48x48.png) ResInsight 1.2 Users Guide ## Introduction From d29590080ea5dd2af38d99668061320733c8b2b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Wed, 2 Jul 2014 11:54:51 +0200 Subject: [PATCH 129/130] Fixed Property filter Crash Introduced by the well cell awareness in faults --- ApplicationCode/ProjectDataModel/RimReservoirView.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp index 8ce24dd443..3438706133 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp @@ -652,10 +652,7 @@ void RimReservoirView::createDisplayModel() updateFaultForcedVisibility(); } - - this->updateFaultColors(); - // Compute triangle count, Debug only if (false) From c96169c62e52ba9b7ec5eba6cc2b0a6ab16ff4c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Wed, 2 Jul 2014 14:11:56 +0200 Subject: [PATCH 130/130] Fixed crash in loading Statistics RegTest manually --- ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp | 7 +++++-- ApplicationCode/ProjectDataModel/RimFaultCollection.cpp | 2 +- OctavePlugin/OctaveScripts/kslice.m | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp index 88a70ef1d2..5ac14e77ce 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp @@ -41,8 +41,11 @@ void RivReservoirPartMgr::clearAndSetReservoir(const RigCaseData* eclipseCase, c m_allGrids.push_back(new RivGridPartMgr(grids[i], i, faultCollection)); } - // Faults read from file are present only on main grid - m_faultsPartMgr = new RivReservoirFaultsPartMgr(eclipseCase->mainGrid(), faultCollection); + if (eclipseCase->mainGrid()) + { + // Faults read from file are present only on main grid + m_faultsPartMgr = new RivReservoirFaultsPartMgr(eclipseCase->mainGrid(), faultCollection); + } } } diff --git a/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp b/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp index 062719de3c..b6a201af09 100644 --- a/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp @@ -187,7 +187,7 @@ bool faultComparator(const cvf::ref& a, const cvf::ref& b) //-------------------------------------------------------------------------------------------------- void RimFaultCollection::syncronizeFaults() { - if (!(m_reservoirView && m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData()) ) return; + if (!(m_reservoirView && m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData() && m_reservoirView->eclipseCase()->reservoirData()->mainGrid()) ) return; cvf::ref partColors = RivColorTableArray::colorTableArray(); diff --git a/OctavePlugin/OctaveScripts/kslice.m b/OctavePlugin/OctaveScripts/kslice.m index 4049e6c80d..a0f8cc5141 100644 --- a/OctavePlugin/OctaveScripts/kslice.m +++ b/OctavePlugin/OctaveScripts/kslice.m @@ -1,4 +1,4 @@ -addpath("/home/builder/Projects/ResInsightBuildDir/OctavePlugin"); + CInfo = riGetActiveCellInfo(); SOIL = riGetActiveCellProperty("SOIL");