diff --git a/ApplicationCode/Application/RiaApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp index 6278ddb2c4..d419d0e0e3 100644 --- a/ApplicationCode/Application/RiaApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -71,6 +71,7 @@ #include "RimSummaryCaseMainCollection.h" #include "RimSummaryCrossPlotCollection.h" #include "RimSummaryPlot.h" +#include "RimSurfaceCollection.h" #include "RimTextAnnotation.h" #include "RimTextAnnotationInView.h" #include "RimViewLinker.h" @@ -541,6 +542,8 @@ bool RiaApplication::loadProject( const QString& projectFileName, fracture->loadDataAndUpdate(); } } + + oilField->surfaceCollection()->loadData(); } // If load action is specified to recalculate statistics, do it now. diff --git a/ApplicationCode/CMakeLists.txt b/ApplicationCode/CMakeLists.txt index a524a67933..a7cbf3d4e1 100644 --- a/ApplicationCode/CMakeLists.txt +++ b/ApplicationCode/CMakeLists.txt @@ -57,6 +57,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/ModelVisualization ${CMAKE_CURRENT_SOURCE_DIR}/ModelVisualization/GridBox ${CMAKE_CURRENT_SOURCE_DIR}/ModelVisualization/Intersections + ${CMAKE_CURRENT_SOURCE_DIR}/ModelVisualization/Surfaces ${CMAKE_CURRENT_SOURCE_DIR}/UserInterface ${CMAKE_CURRENT_SOURCE_DIR}/CommandFileInterface ${CMAKE_CURRENT_SOURCE_DIR}/CommandFileInterface/Core @@ -68,6 +69,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel/GridCrossPlots ${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel/Measurement ${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel/Summary + ${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel/Surfaces ${CMAKE_CURRENT_SOURCE_DIR}/ResultStatisticsCache ${CMAKE_CURRENT_SOURCE_DIR}/ReservoirDataModel @@ -134,12 +136,14 @@ list( APPEND REFERENCED_CMAKE_FILES ProjectDataModel/Completions/CMakeLists_files.cmake ProjectDataModel/Measurement/CMakeLists_files.cmake ProjectDataModel/PlotTemplates/CMakeLists_files.cmake + ProjectDataModel/Surfaces/CMakeLists_files.cmake GeoMech/GeoMechVisualization/CMakeLists_files.cmake ModelVisualization/CMakeLists_files.cmake ModelVisualization/GridBox/CMakeLists_files.cmake ModelVisualization/Intersections/CMakeLists_files.cmake + ModelVisualization/Surfaces/CMakeLists_files.cmake ModelVisualization/WindowEdgeAxesOverlayItem/CMakeLists_files.cmake UserInterface/CMakeLists_files.cmake @@ -163,6 +167,7 @@ list( APPEND REFERENCED_CMAKE_FILES Commands/OperationsUsingObjReferences/CMakeLists_files.cmake Commands/SummaryPlotCommands/CMakeLists_files.cmake Commands/SsiHubImportCommands/CMakeLists_files.cmake + Commands/SurfaceCommands/CMakeLists_files.cmake Commands/ToggleCommands/CMakeLists_files.cmake Commands/ViewLink/CMakeLists_files.cmake Commands/WellLogCommands/CMakeLists_files.cmake diff --git a/ApplicationCode/Commands/RicDeleteItemExec.cpp b/ApplicationCode/Commands/RicDeleteItemExec.cpp index 9de44b415c..b5ab9656ed 100644 --- a/ApplicationCode/Commands/RicDeleteItemExec.cpp +++ b/ApplicationCode/Commands/RicDeleteItemExec.cpp @@ -22,6 +22,7 @@ #include "RiaGuiApplication.h" +#include "Rim2dIntersectionViewCollection.h" #include "Rim3dView.h" #include "RimAnnotationCollection.h" #include "RimAnnotationInViewCollection.h" @@ -33,6 +34,7 @@ #include "RimEnsembleCurveSet.h" #include "RimEnsembleCurveSetCollection.h" #include "RimFormationNamesCollection.h" +#include "RimFractureTemplateCollection.h" #include "RimGeoMechPropertyFilterCollection.h" #include "RimIntersectionCollection.h" #include "RimIntersectionResultsDefinitionCollection.h" @@ -41,6 +43,7 @@ #include "RimSummaryCrossPlotCollection.h" #include "RimSummaryPlot.h" #include "RimSummaryPlotCollection.h" +#include "RimSurfaceCollection.h" #include "RimViewLinkerCollection.h" #include "RimWellLogPlot.h" #include "RimWellLogPlotCollection.h" @@ -50,9 +53,6 @@ #include "RiuPlotMainWindow.h" -#include "RimFractureTemplateCollection.h" - -#include "Rim2dIntersectionViewCollection.h" #include "cafNotificationCenter.h" #include "cafPdmChildArrayField.h" #include "cafPdmDocument.h" @@ -329,6 +329,15 @@ void RicDeleteItemExec::redo() annotationColl->onAnnotationDeleted(); } } + + { + RimSurfaceCollection* surfCollection; + parentObj->firstAncestorOrThisOfType( surfCollection ); + if ( surfCollection ) + { + surfCollection->updateViews(); + } + } } } diff --git a/ApplicationCode/Commands/RicDeleteItemFeature.cpp b/ApplicationCode/Commands/RicDeleteItemFeature.cpp index 7245dce8e9..d53e329c9b 100644 --- a/ApplicationCode/Commands/RicDeleteItemFeature.cpp +++ b/ApplicationCode/Commands/RicDeleteItemFeature.cpp @@ -54,6 +54,7 @@ #include "RimSummaryCurve.h" #include "RimSummaryCurveFilter.h" #include "RimSummaryPlot.h" +#include "RimSurface.h" #include "RimTextAnnotation.h" #include "RimViewController.h" #include "RimWellAllocationPlot.h" @@ -139,6 +140,7 @@ bool isDeletable( caf::PdmUiItem* uiItem ) if ( dynamic_cast( uiItem ) ) return true; if ( dynamic_cast( uiItem ) ) return true; if ( dynamic_cast( uiItem ) ) return true; + if ( dynamic_cast( uiItem ) ) return true; if ( dynamic_cast( uiItem ) ) { diff --git a/ApplicationCode/Commands/RicNewViewFeature.cpp b/ApplicationCode/Commands/RicNewViewFeature.cpp index baeb546981..cda5b22e65 100644 --- a/ApplicationCode/Commands/RicNewViewFeature.cpp +++ b/ApplicationCode/Commands/RicNewViewFeature.cpp @@ -89,7 +89,7 @@ void RicNewViewFeature::setupActionLook( QAction* actionToSetup ) //-------------------------------------------------------------------------------------------------- Rim3dView* RicNewViewFeature::createReservoirView( RimEclipseCase* eclipseCase, RimGeoMechCase* geomCase ) { - Rim3dView* insertedView = nullptr; + RimGridView* insertedView = nullptr; if ( eclipseCase ) { @@ -100,6 +100,8 @@ Rim3dView* RicNewViewFeature::createReservoirView( RimEclipseCase* eclipseCase, insertedView = geomCase->createAndAddReservoirView(); } + insertedView->updateSurfacesInViewTreeItems(); + // Must be run before buildViewItems, as wells are created in this function insertedView->loadDataAndUpdate(); diff --git a/ApplicationCode/Commands/SurfaceCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/SurfaceCommands/CMakeLists_files.cmake new file mode 100644 index 0000000000..b82d21f0ee --- /dev/null +++ b/ApplicationCode/Commands/SurfaceCommands/CMakeLists_files.cmake @@ -0,0 +1,30 @@ + +set (SOURCE_GROUP_HEADER_FILES +${CMAKE_CURRENT_LIST_DIR}/RicImportSurfacesFeature.h +) + +set (SOURCE_GROUP_SOURCE_FILES +${CMAKE_CURRENT_LIST_DIR}/RicImportSurfacesFeature.cpp +) + +list(APPEND CODE_HEADER_FILES +${SOURCE_GROUP_HEADER_FILES} +) + +list(APPEND CODE_SOURCE_FILES +${SOURCE_GROUP_SOURCE_FILES} +) + +#set (QT_MOC_HEADERS +#${QT_MOC_HEADERS} +#${CMAKE_CURRENT_LIST_DIR}/RicTextAnnotation3dEditor.h +#) + + +source_group( "CommandFeature\\SurfaceCommands" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake ) + +# cotire +caf_cotire_start_unity_at_first_item(SOURCE_GROUP_SOURCE_FILES) +list(APPEND CAF_COTIRE_START_NEW_UNITY_SOURCES +${CMAKE_CURRENT_LIST_DIR}/RicImportSurfacesFeature.cpp +) diff --git a/ApplicationCode/Commands/SurfaceCommands/RicImportSurfacesFeature.cpp b/ApplicationCode/Commands/SurfaceCommands/RicImportSurfacesFeature.cpp new file mode 100644 index 0000000000..12d4b6a496 --- /dev/null +++ b/ApplicationCode/Commands/SurfaceCommands/RicImportSurfacesFeature.cpp @@ -0,0 +1,89 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicImportSurfacesFeature.h" + +#include "RiaApplication.h" + +#include "RimOilField.h" +#include "RimProject.h" +#include "RimSurface.h" +#include "RimSurfaceCollection.h" + +#include "Riu3DMainWindowTools.h" + +#include +#include + +CAF_CMD_SOURCE_INIT( RicImportSurfacesFeature, "RicImportSurfacesFeature" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicImportSurfacesFeature::isCommandEnabled() +{ + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicImportSurfacesFeature::onActionTriggered( bool isChecked ) +{ + RiaApplication* app = RiaApplication::instance(); + QString defaultDir = app->lastUsedDialogDirectory( "BINARY_GRID" ); + QStringList fileNames = QFileDialog::getOpenFileNames( Riu3DMainWindowTools::mainWindowWidget(), + "Import Surfaces", + defaultDir, + "Petrel surface file (*.ptl);All Files (*.*)" ); + + if ( fileNames.isEmpty() ) return; + + // Remember the path to next time + app->setLastUsedDialogDirectory( "BINARY_GRID", QFileInfo( fileNames.last() ).absolutePath() ); + + // Find or create the SurfaceCollection + + RimProject* proj = RiaApplication::instance()->project(); + RimSurfaceCollection* surfColl = proj->activeOilField()->surfaceCollection(); + + if ( !surfColl ) + { + surfColl = new RimSurfaceCollection(); + proj->activeOilField()->surfaceCollection = surfColl; + proj->updateConnectedEditors(); + } + + // For each file, + + RimSurface* lastCreatedOrUpdated = surfColl->importSurfacesFromFiles( fileNames ); + + if ( lastCreatedOrUpdated ) + { + Riu3DMainWindowTools::selectAsCurrentItem( lastCreatedOrUpdated ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicImportSurfacesFeature::setupActionLook( QAction* actionToSetup ) +{ + actionToSetup->setIcon( QIcon( ":/ReservoirSurfaces16x16.png" ) ); + actionToSetup->setText( "Import Surfaces" ); +} diff --git a/ApplicationCode/Commands/SurfaceCommands/RicImportSurfacesFeature.h b/ApplicationCode/Commands/SurfaceCommands/RicImportSurfacesFeature.h new file mode 100644 index 0000000000..5dc920b845 --- /dev/null +++ b/ApplicationCode/Commands/SurfaceCommands/RicImportSurfacesFeature.h @@ -0,0 +1,35 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicImportSurfacesFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; +}; diff --git a/ApplicationCode/ModelVisualization/Surfaces/CMakeLists_files.cmake b/ApplicationCode/ModelVisualization/Surfaces/CMakeLists_files.cmake new file mode 100644 index 0000000000..f7c6fab97f --- /dev/null +++ b/ApplicationCode/ModelVisualization/Surfaces/CMakeLists_files.cmake @@ -0,0 +1,18 @@ + +set (SOURCE_GROUP_HEADER_FILES +${CMAKE_CURRENT_LIST_DIR}/RivSurfacePartMgr.h +) + +set (SOURCE_GROUP_SOURCE_FILES +${CMAKE_CURRENT_LIST_DIR}/RivSurfacePartMgr.cpp +) + +list(APPEND CODE_HEADER_FILES +${SOURCE_GROUP_HEADER_FILES} +) + +list(APPEND CODE_SOURCE_FILES +${SOURCE_GROUP_SOURCE_FILES} +) + +source_group( "ModelVisualization\\Surfaces" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake ) diff --git a/ApplicationCode/ModelVisualization/Surfaces/RivSurfacePartMgr.cpp b/ApplicationCode/ModelVisualization/Surfaces/RivSurfacePartMgr.cpp new file mode 100644 index 0000000000..e163a8b5ed --- /dev/null +++ b/ApplicationCode/ModelVisualization/Surfaces/RivSurfacePartMgr.cpp @@ -0,0 +1,97 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RivSurfacePartMgr.h" + +#include "RigSurface.h" +#include "RimSurface.h" +#include "RimSurfaceInView.h" + +#include "RimCase.h" +#include "cafEffectGenerator.h" +#include "cvfDrawableGeo.h" +#include "cvfModelBasicList.h" +#include "cvfPart.h" +#include "cvfPrimitiveSetIndexedUInt.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivSurfacePartMgr::RivSurfacePartMgr( RimSurfaceInView* surface ) + : m_surfaceInView( surface ) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivSurfacePartMgr::appendNativeGeometryPartsToModel( cvf::ModelBasicList* model, cvf::Transform* scaleTransform ) +{ + if ( m_nativeTrianglesPart.isNull() || m_surfaceInView->surface()->surfaceData() != m_usedSurfaceData.p() ) + { + generateNativePartGeometry(); + } + + if ( m_nativeTrianglesPart.notNull() ) + { + m_nativeTrianglesPart->setTransform( scaleTransform ); + + caf::SurfaceEffectGenerator surfaceGen( cvf::Color4f( m_surfaceInView->surface()->color() ), caf::PO_1 ); + cvf::ref eff = surfaceGen.generateCachedEffect(); + m_nativeTrianglesPart->setEffect( eff.p() ); + + model->addPart( m_nativeTrianglesPart.p() ); + + if ( m_nativeMeshLinesPart.notNull() ) + { + m_nativeMeshLinesPart->setTransform( scaleTransform ); + model->addPart( m_nativeMeshLinesPart.p() ); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivSurfacePartMgr::generateNativePartGeometry() +{ + RimCase* ownerCase; + m_surfaceInView->firstAncestorOrThisOfTypeAsserted( ownerCase ); + cvf::Vec3d displayModOffsett = ownerCase->displayModelOffset(); + + m_usedSurfaceData = m_surfaceInView->surface()->surfaceData(); + + const std::vector& vertices = m_usedSurfaceData->vertices(); + cvf::ref cvfVertices = new cvf::Vec3fArray( vertices.size() ); + for ( size_t i = 0; i < vertices.size(); ++i ) + { + ( *cvfVertices )[i] = cvf::Vec3f( vertices[i] - displayModOffsett ); + } + + const std::vector& triangleIndices = m_usedSurfaceData->triangleIndices(); + cvf::ref cvfIndices = new cvf::UIntArray( triangleIndices ); + cvf::ref indexSet = new cvf::PrimitiveSetIndexedUInt( cvf::PT_TRIANGLES ); + indexSet->setIndices( cvfIndices.p() ); + + cvf::ref drawGeo = new cvf::DrawableGeo; + drawGeo->addPrimitiveSet( indexSet.p() ); + drawGeo->setVertexArray( cvfVertices.p() ); + + m_nativeTrianglesPart = new cvf::Part(); + m_nativeTrianglesPart->setDrawable( drawGeo.p() ); +} diff --git a/ApplicationCode/ModelVisualization/Surfaces/RivSurfacePartMgr.h b/ApplicationCode/ModelVisualization/Surfaces/RivSurfacePartMgr.h new file mode 100644 index 0000000000..7eaf207070 --- /dev/null +++ b/ApplicationCode/ModelVisualization/Surfaces/RivSurfacePartMgr.h @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "cafPdmPointer.h" +#include "cvfObject.h" + +namespace cvf +{ +class ModelBasicList; +class Transform; +class Part; +class ScalarMapper; +class DrawableGeo; +} // namespace cvf + +class RimSurfaceInView; +class RigSurface; + +class RivSurfacePartMgr : public cvf::Object +{ +public: + explicit RivSurfacePartMgr( RimSurfaceInView* surface ); + + void appendNativeGeometryPartsToModel( cvf::ModelBasicList* model, cvf::Transform* scaleTransform ); + +private: + void generateNativePartGeometry(); + + caf::PdmPointer m_surfaceInView; + cvf::ref m_usedSurfaceData; // Store the reference to the old data, to know when new data has arrived. + + cvf::ref m_nativeTrianglesPart; + cvf::ref m_nativeMeshLinesPart; +}; diff --git a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp index dcca90c3b9..0ee4ddf2f1 100644 --- a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -102,6 +102,8 @@ #include "RimSummaryCurveCollection.h" #include "RimSummaryPlot.h" #include "RimSummaryPlotCollection.h" +#include "RimSurface.h" +#include "RimSurfaceCollection.h" #include "RimValveTemplate.h" #include "RimValveTemplateCollection.h" #include "RimViewController.h" @@ -799,6 +801,10 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder << "Separator"; menuBuilder << "RicConvertFractureTemplateUnitFeature"; } + else if ( dynamic_cast( firstUiItem ) || dynamic_cast( firstUiItem ) ) + { + menuBuilder << "RicImportSurfacesFeature"; + } else if ( dynamic_cast( firstUiItem ) || dynamic_cast( firstUiItem ) ) { diff --git a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp index 02b7cfc368..b14484406b 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp @@ -71,6 +71,7 @@ #include "RimSimWellInView.h" #include "RimSimWellInViewCollection.h" #include "RimStimPlanColors.h" +#include "RimSurfaceInViewCollection.h" #include "RimTernaryLegendConfig.h" #include "RimViewController.h" #include "RimViewLinker.h" @@ -538,6 +539,15 @@ void RimEclipseView::onCreateDisplayModel() m_reservoirGridPartManager->scaleTransform() ); nativeOrOverrideViewer()->addStaticModelOnce( m_intersectionVizModel.p(), isUsingOverrideViewer() ); + // Surfaces + + m_surfaceVizModel->removeAllParts(); + if ( m_surfaceCollection ) + { + m_surfaceCollection->appendPartsToModel( m_surfaceVizModel.p(), m_reservoirGridPartManager->scaleTransform() ); + nativeOrOverrideViewer()->addStaticModelOnce( m_surfaceVizModel.p(), isUsingOverrideViewer() ); + } + // Well path model m_wellPathPipeVizModel->removeAllParts(); @@ -1754,6 +1764,8 @@ void RimEclipseView::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrderin uiTreeOrdering.add( annotationCollection() ); uiTreeOrdering.add( intersectionCollection() ); + if ( surfaceInViewCollection() ) uiTreeOrdering.add( surfaceInViewCollection() ); + uiTreeOrdering.add( m_rangeFilterCollection() ); uiTreeOrdering.add( m_propertyFilterCollection() ); uiTreeOrdering.skipRemainingChildren( true ); diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp index 441489a48a..5bc5582631 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp @@ -42,6 +42,7 @@ #include "RimIntersectionResultDefinition.h" #include "RimIntersectionResultsDefinitionCollection.h" #include "RimRegularLegendConfig.h" +#include "RimSurfaceInViewCollection.h" #include "RimTensorResults.h" #include "RimTernaryLegendConfig.h" #include "RimViewLinker.h" @@ -297,6 +298,15 @@ void RimGeoMechView::onCreateDisplayModel() m_intersectionCollection->appendPartsToModel( *this, m_intersectionVizModel.p(), scaleTransform() ); nativeOrOverrideViewer()->addStaticModelOnce( m_intersectionVizModel.p(), isUsingOverrideViewer() ); + // Surfaces + + m_surfaceVizModel->removeAllParts(); + if ( m_surfaceCollection ) + { + m_surfaceCollection->appendPartsToModel( m_surfaceVizModel.p(), scaleTransform() ); + nativeOrOverrideViewer()->addStaticModelOnce( m_surfaceVizModel.p(), isUsingOverrideViewer() ); + } + // If the animation was active before recreating everything, make viewer view current frame if ( isTimeStepDependentDataVisibleInThisOrComparisonView() ) @@ -907,6 +917,7 @@ void RimGeoMechView::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrderin uiTreeOrdering.add( &m_wellMeasurementCollection ); uiTreeOrdering.add( m_intersectionCollection() ); + if ( surfaceInViewCollection() ) uiTreeOrdering.add( surfaceInViewCollection() ); uiTreeOrdering.add( m_rangeFilterCollection() ); uiTreeOrdering.add( m_propertyFilterCollection() ); diff --git a/ApplicationCode/ProjectDataModel/RimGridView.cpp b/ApplicationCode/ProjectDataModel/RimGridView.cpp index 09102a95c2..f69d007875 100644 --- a/ApplicationCode/ProjectDataModel/RimGridView.cpp +++ b/ApplicationCode/ProjectDataModel/RimGridView.cpp @@ -29,8 +29,11 @@ #include "RimGridCollection.h" #include "RimIntersectionCollection.h" #include "RimIntersectionResultsDefinitionCollection.h" +#include "RimOilField.h" #include "RimProject.h" #include "RimPropertyFilterCollection.h" +#include "RimSurfaceCollection.h" +#include "RimSurfaceInViewCollection.h" #include "RimTextAnnotation.h" #include "RimViewController.h" #include "RimViewLinker.h" @@ -45,6 +48,7 @@ #include "RivSingleCellPartGenerator.h" #include "cvfModel.h" +#include "cvfModelBasicList.h" #include "cvfPart.h" #include "cvfScene.h" @@ -97,6 +101,12 @@ RimGridView::RimGridView() CAF_PDM_InitFieldNoDefault( &m_wellMeasurementCollection, "WellMeasurements", "Well Measurements", "", "", "" ); m_wellMeasurementCollection = new RimWellMeasurementInViewCollection; m_wellMeasurementCollection.uiCapability()->setUiHidden( true ); + + CAF_PDM_InitFieldNoDefault( &m_surfaceCollection, "SurfaceInViewCollection", "Surface Collection Field", "", "", "" ); + m_surfaceCollection.uiCapability()->setUiTreeHidden( true ); + + m_surfaceVizModel = new cvf::ModelBasicList; + m_surfaceVizModel->setName( "SurfaceModel" ); } //-------------------------------------------------------------------------------------------------- @@ -174,6 +184,14 @@ RimIntersectionCollection* RimGridView::intersectionCollection() const return m_intersectionCollection(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSurfaceInViewCollection* RimGridView::surfaceInViewCollection() const +{ + return m_surfaceCollection(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -565,3 +583,28 @@ void RimGridView::updateWellMeasurements() { m_wellMeasurementCollection->syncWithChangesInWellMeasurementCollection(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridView::updateSurfacesInViewTreeItems() +{ + RimProject* proj = RiaApplication::instance()->project(); + RimSurfaceCollection* surfColl = proj->activeOilField()->surfaceCollection(); + + if ( surfColl && surfColl->surfaces().size() ) + { + if ( !m_surfaceCollection() ) + { + m_surfaceCollection = new RimSurfaceInViewCollection(); + } + + m_surfaceCollection->updateFromSurfaceCollection(); + } + else + { + delete m_surfaceCollection; + } + + this->updateConnectedEditors(); +} diff --git a/ApplicationCode/ProjectDataModel/RimGridView.h b/ApplicationCode/ProjectDataModel/RimGridView.h index f42388c7f8..1637b3990a 100644 --- a/ApplicationCode/ProjectDataModel/RimGridView.h +++ b/ApplicationCode/ProjectDataModel/RimGridView.h @@ -31,6 +31,7 @@ class RimPropertyFilterCollection; class RimGridCollection; class RimCellRangeFilterCollection; class RimWellMeasurementInViewCollection; +class RimSurfaceInViewCollection; class RimGridView : public Rim3dView { @@ -47,6 +48,7 @@ public: cvf::ref currentTotalCellVisibility(); RimIntersectionCollection* intersectionCollection() const; + RimSurfaceInViewCollection* surfaceInViewCollection() const; RimIntersectionResultsDefinitionCollection* separateIntersectionResultsCollection() const; RimAnnotationInViewCollection* annotationCollection() const; RimWellMeasurementInViewCollection* measurementCollection() const; @@ -72,6 +74,7 @@ public: bool forceChange = false ) override; void updateWellMeasurements(); + void updateSurfacesInViewTreeItems(); protected: virtual void updateViewFollowingRangeFilterUpdates(); @@ -87,6 +90,8 @@ protected: void initAfterRead() override; protected: + cvf::ref m_surfaceVizModel; + // Fields caf::PdmChildField m_intersectionCollection; @@ -98,6 +103,7 @@ protected: caf::PdmChildField m_gridCollection; caf::PdmChildField m_annotationCollection; caf::PdmChildField m_wellMeasurementCollection; + caf::PdmChildField m_surfaceCollection; private: void onCreatePartCollectionFromSelection( cvf::Collection* parts ) override; diff --git a/ApplicationCode/ProjectDataModel/RimOilField.cpp b/ApplicationCode/ProjectDataModel/RimOilField.cpp index 23916d7a35..ec039f9bcf 100644 --- a/ApplicationCode/ProjectDataModel/RimOilField.cpp +++ b/ApplicationCode/ProjectDataModel/RimOilField.cpp @@ -31,6 +31,7 @@ #include "RimObservedSummaryData.h" #include "RimSummaryCase.h" #include "RimSummaryCaseMainCollection.h" +#include "RimSurfaceCollection.h" #include "RimValveTemplateCollection.h" #include "RimWellPathCollection.h" @@ -71,18 +72,20 @@ RimOilField::RimOilField( void ) "", "" ); - completionTemplateCollection = new RimCompletionTemplateCollection; - CAF_PDM_InitFieldNoDefault( &measurement, "Measurement", "Measurement", "", "", "" ); measurement = new RimMeasurement(); measurement.xmlCapability()->disableIO(); - analysisModels = new RimEclipseCaseCollection(); - wellPathCollection = new RimWellPathCollection(); - summaryCaseMainCollection = new RimSummaryCaseMainCollection(); - observedDataCollection = new RimObservedDataCollection(); - formationNamesCollection = new RimFormationNamesCollection(); - annotationCollection = new RimAnnotationCollection(); + CAF_PDM_InitFieldNoDefault( &surfaceCollection, "SurfaceCollection", "Surfaces", "", "", "" ); + surfaceCollection = new RimSurfaceCollection(); + + completionTemplateCollection = new RimCompletionTemplateCollection; + analysisModels = new RimEclipseCaseCollection(); + wellPathCollection = new RimWellPathCollection(); + summaryCaseMainCollection = new RimSummaryCaseMainCollection(); + observedDataCollection = new RimObservedDataCollection(); + formationNamesCollection = new RimFormationNamesCollection(); + annotationCollection = new RimAnnotationCollection(); m_fractureTemplateCollection_OBSOLETE = new RimFractureTemplateCollection; m_fractureTemplateCollection_OBSOLETE.xmlCapability()->setIOWritable( false ); diff --git a/ApplicationCode/ProjectDataModel/RimOilField.h b/ApplicationCode/ProjectDataModel/RimOilField.h index ed7e735306..758a4ff293 100644 --- a/ApplicationCode/ProjectDataModel/RimOilField.h +++ b/ApplicationCode/ProjectDataModel/RimOilField.h @@ -37,6 +37,7 @@ class RimSummaryCaseMainCollection; class RimWellPathCollection; class RimAnnotationCollection; class RimMeasurement; +class RimSurfaceCollection; //================================================================================================== /// @@ -67,6 +68,7 @@ public: caf::PdmChildField formationNamesCollection; caf::PdmChildField annotationCollection; caf::PdmChildField measurement; + caf::PdmChildField surfaceCollection; protected: void initAfterRead() override; diff --git a/ApplicationCode/ProjectDataModel/RimProject.cpp b/ApplicationCode/ProjectDataModel/RimProject.cpp index 9c06f46dae..15c8033eed 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.cpp +++ b/ApplicationCode/ProjectDataModel/RimProject.cpp @@ -70,6 +70,7 @@ #include "RimSummaryCaseMainCollection.h" #include "RimSummaryCrossPlotCollection.h" #include "RimSummaryPlotCollection.h" +#include "RimSurfaceCollection.h" #include "RimTools.h" #include "RimUserDefinedPolylinesAnnotation.h" #include "RimValveTemplate.h" @@ -81,6 +82,7 @@ #include "RimWellLogPlotCollection.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" + #include "SsiHubImportCommands/RimWellPathImport.h" #include "RiuMainWindow.h" @@ -1375,6 +1377,7 @@ void RimProject::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, Q if ( oilField->analysisModels() ) uiTreeOrdering.add( oilField->analysisModels() ); if ( oilField->geoMechModels() ) uiTreeOrdering.add( oilField->geoMechModels() ); if ( oilField->wellPathCollection() ) uiTreeOrdering.add( oilField->wellPathCollection() ); + if ( oilField->surfaceCollection() ) uiTreeOrdering.add( oilField->surfaceCollection() ); if ( oilField->formationNamesCollection() ) uiTreeOrdering.add( oilField->formationNamesCollection() ); if ( oilField->completionTemplateCollection() ) uiTreeOrdering.add( oilField->completionTemplateCollection() ); @@ -1396,7 +1399,7 @@ class GlobalPathListMapper public: GlobalPathListMapper( const QString& globalPathListTable ) { - m_nextValidIdNumber = 1; + m_maxUsedIdNumber = 0; QStringList pathPairs = globalPathListTable.split( ";", QString::SkipEmptyParts ); for ( const QString& pathIdPathPair : pathPairs ) @@ -1419,7 +1422,7 @@ public: if ( isOk ) { - m_nextValidIdNumber = std::max( m_nextValidIdNumber, idNumber ); + m_maxUsedIdNumber = std::max( m_maxUsedIdNumber, idNumber ); } } @@ -1513,13 +1516,15 @@ public: private: QString createUnusedId() { - QString numberString = QString( "%1" ).arg( (uint)m_nextValidIdNumber, 3, 10, QChar( '0' ) ); + m_maxUsedIdNumber++; + + QString numberString = QString( "%1" ).arg( (uint)m_maxUsedIdNumber, 3, 10, QChar( '0' ) ); QString pathIdentifier = PATHIDCHAR + pathIdBaseString + numberString + PATHIDCHAR; - m_nextValidIdNumber++; + return pathIdentifier; } - size_t m_nextValidIdNumber; // Set when parsing the globalPathListTable. Increment while creating new id's + size_t m_maxUsedIdNumber; // Set when parsing the globalPathListTable. Increment while creating new id's std::map m_newPathIdToPathMap; std::map m_newPathToPathIdMap; diff --git a/ApplicationCode/ProjectDataModel/RimProject.h b/ApplicationCode/ProjectDataModel/RimProject.h index 808fdc40f2..4bfd84414f 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.h +++ b/ApplicationCode/ProjectDataModel/RimProject.h @@ -193,7 +193,7 @@ protected: private: template - void fieldContentsByType( caf::PdmObjectHandle* object, std::vector& typedFields ); + void fieldContentsByType( caf::PdmObjectHandle* object, std::vector& fieldContents ); void transferPathsToGlobalPathList(); void distributePathsFromGlobalPathList(); @@ -225,7 +225,7 @@ private: /// //-------------------------------------------------------------------------------------------------- template -void RimProject::fieldContentsByType( caf::PdmObjectHandle* object, std::vector& typedFields ) +void RimProject::fieldContentsByType( caf::PdmObjectHandle* object, std::vector& fieldContents ) { if ( !object ) return; @@ -237,14 +237,14 @@ void RimProject::fieldContentsByType( caf::PdmObjectHandle* object, std::vector< for ( const auto& field : allFieldsInObject ) { caf::PdmField* typedField = dynamic_cast*>( field ); - if ( typedField ) typedFields.push_back( &typedField->v() ); + if ( typedField ) fieldContents.push_back( &typedField->v() ); caf::PdmField>* typedFieldInVector = dynamic_cast>*>( field ); if ( typedFieldInVector ) { for ( T& typedFieldFromVector : typedFieldInVector->v() ) { - typedFields.push_back( &typedFieldFromVector ); + fieldContents.push_back( &typedFieldFromVector ); } } @@ -253,6 +253,6 @@ void RimProject::fieldContentsByType( caf::PdmObjectHandle* object, std::vector< for ( const auto& child : children ) { - fieldContentsByType( child, typedFields ); + fieldContentsByType( child, fieldContents ); } } diff --git a/ApplicationCode/ProjectDataModel/Surfaces/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/Surfaces/CMakeLists_files.cmake new file mode 100644 index 0000000000..b58187b478 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Surfaces/CMakeLists_files.cmake @@ -0,0 +1,24 @@ + +set (SOURCE_GROUP_HEADER_FILES +${CMAKE_CURRENT_LIST_DIR}/RimSurface.h +${CMAKE_CURRENT_LIST_DIR}/RimSurfaceCollection.h +${CMAKE_CURRENT_LIST_DIR}/RimSurfaceInView.h +${CMAKE_CURRENT_LIST_DIR}/RimSurfaceInViewCollection.h +) + +set (SOURCE_GROUP_SOURCE_FILES +${CMAKE_CURRENT_LIST_DIR}/RimSurface.cpp +${CMAKE_CURRENT_LIST_DIR}/RimSurfaceCollection.cpp +${CMAKE_CURRENT_LIST_DIR}/RimSurfaceInView.cpp +${CMAKE_CURRENT_LIST_DIR}/RimSurfaceInViewCollection.cpp +) + +list(APPEND CODE_HEADER_FILES +${SOURCE_GROUP_HEADER_FILES} +) + +list(APPEND CODE_SOURCE_FILES +${SOURCE_GROUP_SOURCE_FILES} +) + +source_group( "ProjectDataModel\\Surface" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake ) diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimSurface.cpp b/ApplicationCode/ProjectDataModel/Surfaces/RimSurface.cpp new file mode 100644 index 0000000000..9e4f651a4c --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimSurface.cpp @@ -0,0 +1,266 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#include "RimSurface.h" + +#include "RimSurfaceCollection.h" + +#include "RigSurface.h" + +#include + +#include +#include + +CAF_PDM_SOURCE_INIT( RimSurface, "Surface" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSurface::RimSurface() +{ + CAF_PDM_InitObject( "Surface", ":/ReservoirSurface16x16.png", "", "" ); + + CAF_PDM_InitFieldNoDefault( &m_userDescription, "SurfaceUserDecription", "Name", "", "", "" ); + CAF_PDM_InitFieldNoDefault( &m_surfaceDefinitionFilePath, "SurfaceFilePath", "File", "", "", "" ); + CAF_PDM_InitField( &m_color, "SurfaceColor", cvf::Color3f( 0.5f, 0.3f, 0.2f ), "Color", "", "", "" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSurface::~RimSurface() {} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurface::setSurfaceFilePath( const QString& filePath ) +{ + m_surfaceDefinitionFilePath = filePath; + if ( m_userDescription().isEmpty() ) + { + m_userDescription = QFileInfo( filePath ).fileName(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimSurface::surfaceFilePath() +{ + return m_surfaceDefinitionFilePath().path(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurface::setColor( const cvf::Color3f& color ) +{ + m_color = color; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color3f RimSurface::color() const +{ + return m_color(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimSurface::userDescription() +{ + return m_userDescription(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigSurface* RimSurface::surfaceData() +{ + return m_surfaceData.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimSurface::userDescriptionField() +{ + return &m_userDescription; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurface::fieldChangedByUi( const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue ) +{ + if ( changedField == &m_surfaceDefinitionFilePath ) + { + updateSurfaceDataFromFile(); + + RimSurfaceCollection* surfColl; + this->firstAncestorOrThisOfTypeAsserted( surfColl ); + surfColl->updateViews( {this} ); + } + else if ( changedField == &m_color ) + { + RimSurfaceCollection* surfColl; + this->firstAncestorOrThisOfTypeAsserted( surfColl ); + surfColl->updateViews( {this} ); + } +} + +struct SurfacePointData +{ + int i; + int j; + cvf::Vec3d point; + std::vector values; +}; + +//-------------------------------------------------------------------------------------------------- +/// Returns false for fatal failure +//-------------------------------------------------------------------------------------------------- +bool RimSurface::updateSurfaceDataFromFile() +{ + std::ifstream stream( this->surfaceFilePath().toLatin1().data() ); + + std::vector surfaceDataPoints; + int minI = std::numeric_limits::max(); + int minJ = std::numeric_limits::max(); + int maxI = std::numeric_limits::min(); + int maxJ = std::numeric_limits::min(); + + while ( stream.good() ) + { + std::string line; + std::getline( stream, line ); + std::istringstream lineStream( line ); + + double x( HUGE_VAL ), y( HUGE_VAL ), z( HUGE_VAL ); + int i( -1 ), j( -1 ); + std::vector values; + + // First check if we can read a number + + lineStream >> x; + if ( lineStream.good() ) // If we can, assume this line is a surface point + { + lineStream >> y >> z >> i >> j; + + if ( x != HUGE_VAL && y != HUGE_VAL && z != HUGE_VAL && i != -1 && j != -1 ) + { + // Check for extra data + while ( lineStream.good() ) + { + double d; + lineStream >> d; + if ( lineStream.good() ) values.push_back( d ); + } + + // Add point + + surfaceDataPoints.push_back( {i, j, {x, y, z}, values} ); + + minI = std::min( minI, i ); + minJ = std::min( minJ, j ); + maxI = std::max( maxI, i ); + maxJ = std::max( maxJ, j ); + } + } + else // Probably a comment line, skip + { + } + } + + // clang-format off + if ( surfaceDataPoints.empty() + || minI == std::numeric_limits::max() + || minJ == std::numeric_limits::max() + || maxI == std::numeric_limits::min() + || maxJ == std::numeric_limits::min() ) + { + return false; + } + // clang-format on + + // Create full size grid matrix + + size_t iCount = maxI - minI + 1; + size_t jCount = maxJ - minJ + 1; + + if ( iCount < 2 || jCount < 2 ) + { + return false; + } + + std::vector> indexToPointData; + indexToPointData.resize( iCount, std::vector( jCount, -1 ) ); + std::vector vertices; + + for ( unsigned pIdx = 0; pIdx < surfaceDataPoints.size(); ++pIdx ) + { + const auto& pointData = surfaceDataPoints[pIdx]; + + indexToPointData[pointData.i - minI][pointData.j - minJ] = pIdx; + + vertices.push_back( pointData.point ); + // Todo: Move result values for each point into the + } + + std::vector triangleIndices; + if ( indexToPointData.size() < 2 ) + { + return false; + } + + for ( size_t iIdx = 0; iIdx < indexToPointData.size() - 1; ++iIdx ) + { + for ( size_t jIdx = 0; jIdx < indexToPointData[iIdx].size() - 1; ++jIdx ) + { + { + unsigned q1 = indexToPointData[iIdx + 0][jIdx + 0]; + unsigned q2 = indexToPointData[iIdx + 0][jIdx + 1]; + unsigned q3 = indexToPointData[iIdx + 1][jIdx + 0]; + unsigned q4 = indexToPointData[iIdx + 1][jIdx + 1]; + + if ( q1 != -1 && q2 != -1 && q4 != -1 ) + { + triangleIndices.push_back( q1 ); + triangleIndices.push_back( q2 ); + triangleIndices.push_back( q4 ); + } + + if ( q1 != -1 && q2 != -1 && q3 != -1 ) + { + triangleIndices.push_back( q1 ); + triangleIndices.push_back( q4 ); + triangleIndices.push_back( q3 ); + } + } + } + } + + m_surfaceData = new RigSurface(); + m_surfaceData->setTriangleData( triangleIndices, vertices ); + + return true; +} diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimSurface.h b/ApplicationCode/ProjectDataModel/Surfaces/RimSurface.h new file mode 100644 index 0000000000..3c652828c5 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimSurface.h @@ -0,0 +1,59 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObject.h" + +#include "cvfObject.h" + +#include "cafPdmFieldCvfColor.h" + +class RigSurface; + +class RimSurface : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimSurface(); + ~RimSurface() override; + + void setSurfaceFilePath( const QString& filePath ); + QString surfaceFilePath(); + + void setColor( const cvf::Color3f& color ); + cvf::Color3f color() const; + + bool updateSurfaceDataFromFile(); + RigSurface* surfaceData(); + + QString userDescription(); + +private: + caf::PdmFieldHandle* userDescriptionField() override; + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue ) override; + + caf::PdmField m_surfaceDefinitionFilePath; + caf::PdmField m_userDescription; + caf::PdmField m_color; + + cvf::ref m_surfaceData; +}; diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceCollection.cpp b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceCollection.cpp new file mode 100644 index 0000000000..c6b5e107b9 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceCollection.cpp @@ -0,0 +1,209 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimSurfaceCollection.h" +#include "QMessageBox" +#include "RiaApplication.h" +#include "RiaColorTables.h" +#include "RimGridView.h" +#include "RimProject.h" +#include "RimSurface.h" +#include "RimSurfaceInView.h" + +CAF_PDM_SOURCE_INIT( RimSurfaceCollection, "SurfaceCollection" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSurfaceCollection::RimSurfaceCollection() +{ + CAF_PDM_InitObject( "Surfaces", ":/ReservoirSurfaces16x16.png", "", "" ); + + CAF_PDM_InitFieldNoDefault( &m_surfaces, "SurfacesField", "Surfaces", "", "", "" ); + m_surfaces.uiCapability()->setUiTreeHidden( true ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSurfaceCollection::~RimSurfaceCollection() {} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurfaceCollection::addSurface( RimSurface* surface ) +{ + m_surfaces.push_back( surface ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSurface* RimSurfaceCollection::importSurfacesFromFiles( const QStringList& fileNames ) +{ + QStringList newFileNames; + std::vector surfacesToReload; + + for ( const QString& newFileName : fileNames ) + { + bool isFound = false; + for ( RimSurface* surface : m_surfaces() ) + { + if ( surface->surfaceFilePath() == newFileName ) + { + surfacesToReload.push_back( surface ); + isFound = true; + break; + } + } + + if ( !isFound ) + { + newFileNames.push_back( newFileName ); + } + } + + size_t newSurfCount = 0; + size_t existingSurfCount = m_surfaces().size(); + QString errorMessages; + + for ( const QString& newFileName : newFileNames ) + { + RimSurface* newSurface = new RimSurface; + + auto newColor = RiaColorTables::categoryPaletteColors().cycledColor3f( existingSurfCount + newSurfCount ); + + newSurface->setSurfaceFilePath( newFileName ); + newSurface->setColor( newColor ); + + if ( !newSurface->updateSurfaceDataFromFile() ) + { + delete newSurface; + errorMessages += newFileName + "\n"; + } + else + { + this->addSurface( newSurface ); + surfacesToReload.push_back( newSurface ); + + ++newSurfCount; + } + } + + if ( !errorMessages.isEmpty() ) + { + QMessageBox::warning( nullptr, "Import Surfaces:", "Could not import the following files:\n" + errorMessages ); + } + + this->updateConnectedEditors(); + + updateViews( surfacesToReload ); + + if ( !newFileNames.empty() ) + { + return m_surfaces[m_surfaces.size() - 1]; + } + else + { + return nullptr; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimSurfaceCollection::surfaces() const +{ + return m_surfaces.childObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurfaceCollection::loadData() +{ + for ( auto surf : m_surfaces ) + { + if ( !surf->updateSurfaceDataFromFile() ) + { + // Error: could not open the surface file surf->surfaceFilePath(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurfaceCollection::updateViews( const std::vector& surfsToReload ) +{ + RimProject* proj = RiaApplication::instance()->project(); + + std::vector views; + proj->allViews( views ); + + // Make sure the tree items are syncronized + + for ( auto view : views ) + { + auto gridView = dynamic_cast( view ); + if ( gridView ) gridView->updateSurfacesInViewTreeItems(); + } + + std::set viewsNeedingUpdate; + + for ( auto surf : surfsToReload ) + { + std::vector surfsInView; + surf->objectsWithReferringPtrFieldsOfType( surfsInView ); + for ( auto surfInView : surfsInView ) + { + RimGridView* gridView; + surfInView->firstAncestorOrThisOfType( gridView ); + + if ( gridView ) viewsNeedingUpdate.insert( gridView ); + } + } + + // Update the views: + for ( auto view : viewsNeedingUpdate ) + { + view->scheduleCreateDisplayModelAndRedraw(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurfaceCollection::updateViews() +{ + RimProject* proj = RiaApplication::instance()->project(); + std::vector views; + proj->allVisibleGridViews( views ); + + // Make sure the tree items are syncronized + + for ( auto view : views ) + { + view->updateSurfacesInViewTreeItems(); + } + + for ( auto view : views ) + { + view->scheduleCreateDisplayModelAndRedraw(); + } +} diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceCollection.h b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceCollection.h new file mode 100644 index 0000000000..5f5542a7f4 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceCollection.h @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "cafPdmChildArrayField.h" +#include "cafPdmObject.h" + +class RimSurface; + +class RimSurfaceCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimSurfaceCollection(); + ~RimSurfaceCollection() override; + + void addSurface( RimSurface* surface ); + + RimSurface* importSurfacesFromFiles( const QStringList& fileNames ); + + std::vector surfaces() const; + + void loadData(); + void updateViews(); + void updateViews( const std::vector& surfsToReload ); + +private: + caf::PdmChildArrayField m_surfaces; +}; diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInView.cpp b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInView.cpp new file mode 100644 index 0000000000..efc4d93d1b --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInView.cpp @@ -0,0 +1,136 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimSurfaceInView.h" + +#include "RimGridView.h" +#include "RimSurface.h" + +#include "RivSurfacePartMgr.h" + +CAF_PDM_SOURCE_INIT( RimSurfaceInView, "SurfaceInView" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSurfaceInView::RimSurfaceInView() +{ + CAF_PDM_InitObject( "Surface", ":/ReservoirSurface16x16.png", "", "" ); + + CAF_PDM_InitField( &m_isActive, "IsActive", true, "Visible", "", "", "" ); + m_isActive.uiCapability()->setUiHidden( true ); + + CAF_PDM_InitFieldNoDefault( &m_name, "Name", "Name", "", "", "" ); + m_name.registerGetMethod( this, &RimSurfaceInView::name ); + + CAF_PDM_InitFieldNoDefault( &m_surface, "SurfaceRef", "Surface", "", "", "" ); + m_surface.uiCapability()->setUiHidden( true ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSurfaceInView::~RimSurfaceInView() {} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimSurfaceInView::name() const +{ + if ( m_surface ) return m_surface->userDescription(); + + return ""; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurfaceInView::loadDataAndUpdate() {} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSurface* RimSurfaceInView::surface() const +{ + return m_surface(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurfaceInView::setSurface( RimSurface* surf ) +{ + m_surface = surf; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimSurfaceInView::isActive() +{ + return m_isActive(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurfaceInView::clearGeometry() +{ + m_surfacePartMgr = nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivSurfacePartMgr* RimSurfaceInView::surfacePartMgr() +{ + if ( m_surfacePartMgr.isNull() ) m_surfacePartMgr = new RivSurfacePartMgr( this ); + + return m_surfacePartMgr.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurfaceInView::fieldChangedByUi( const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue ) +{ + if ( changedField == &m_isActive ) + { + RimGridView* ownerView; + this->firstAncestorOrThisOfTypeAsserted( ownerView ); + ownerView->scheduleCreateDisplayModelAndRedraw(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimSurfaceInView::userDescriptionField() +{ + return &m_name; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimSurfaceInView::objectToggleField() +{ + return &m_isActive; +} diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInView.h b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInView.h new file mode 100644 index 0000000000..2177a7c2d5 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInView.h @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmPtrField.h" + +#include "cvfObject.h" + +class RimSurface; +class RivSurfacePartMgr; + +class RimSurfaceInView : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimSurfaceInView(); + ~RimSurfaceInView() override; + + void loadDataAndUpdate(); + + QString name() const; + RimSurface* surface() const; + void setSurface( RimSurface* surf ); + bool isActive(); + + void clearGeometry(); + RivSurfacePartMgr* surfacePartMgr(); + +private: + caf::PdmFieldHandle* userDescriptionField() override; + caf::PdmFieldHandle* objectToggleField() override; + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue ) override; + + caf::PdmProxyValueField m_name; + caf::PdmField m_isActive; + caf::PdmPtrField m_surface; + + cvf::ref m_surfacePartMgr; +}; diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInViewCollection.cpp b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInViewCollection.cpp new file mode 100644 index 0000000000..07c58581cd --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInViewCollection.cpp @@ -0,0 +1,149 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimSurfaceInViewCollection.h" + +#include "RiaApplication.h" +#include "RimGridView.h" +#include "RimOilField.h" +#include "RimProject.h" +#include "RimSurfaceCollection.h" +#include "RimSurfaceInView.h" + +#include "RivSurfacePartMgr.h" + +#include "cvfModelBasicList.h" + +CAF_PDM_SOURCE_INIT( RimSurfaceInViewCollection, "SurfaceInViewCollection" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSurfaceInViewCollection::RimSurfaceInViewCollection() +{ + CAF_PDM_InitObject( "Surfaces", ":/ReservoirSurfaces16x16.png", "", "" ); + + CAF_PDM_InitField( &m_isActive, "isActive", true, "Active", "", "", "" ); + m_isActive.uiCapability()->setUiHidden( true ); + + CAF_PDM_InitFieldNoDefault( &m_surfacesInView, "SurfacesInViewField", "SurfacesInViewField", "", "", "" ); + m_surfacesInView.uiCapability()->setUiTreeHidden( true ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSurfaceInViewCollection::~RimSurfaceInViewCollection() {} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurfaceInViewCollection::updateFromSurfaceCollection() +{ + // Delete surfaceInView without any real Surface connection + + std::vector surfsInView = m_surfacesInView.childObjects(); + + for ( auto surf : surfsInView ) + { + if ( !surf->surface() ) + { + m_surfacesInView.removeChildObject( surf ); + delete surf; + } + } + + // Create new entries + + RimProject* proj = RiaApplication::instance()->project(); + RimSurfaceCollection* surfColl = proj->activeOilField()->surfaceCollection(); + + if ( surfColl ) + { + std::vector surfs = surfColl->surfaces(); + + for ( auto surf : surfs ) + { + if ( !this->hasSurfaceInViewForSurface( surf ) ) + { + RimSurfaceInView* newSurfInView = new RimSurfaceInView(); + newSurfInView->setSurface( surf ); + m_surfacesInView.push_back( newSurfInView ); + } + } + } + + this->updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurfaceInViewCollection::appendPartsToModel( cvf::ModelBasicList* model, cvf::Transform* scaleTransform ) +{ + if ( !m_isActive() ) return; + + for ( RimSurfaceInView* surf : m_surfacesInView ) + { + if ( surf->isActive() ) + { + surf->surfacePartMgr()->appendNativeGeometryPartsToModel( model, scaleTransform ); + } + } + + model->updateBoundingBoxesRecursive(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurfaceInViewCollection::fieldChangedByUi( const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue ) +{ + if ( changedField == &m_isActive ) + { + RimGridView* ownerView; + this->firstAncestorOrThisOfTypeAsserted( ownerView ); + ownerView->scheduleCreateDisplayModelAndRedraw(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimSurfaceInViewCollection::hasSurfaceInViewForSurface( const RimSurface* surf ) const +{ + for ( auto surfInView : m_surfacesInView ) + { + if ( surfInView->surface() == surf ) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimSurfaceInViewCollection::objectToggleField() +{ + return &m_isActive; +} diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInViewCollection.h b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInViewCollection.h new file mode 100644 index 0000000000..f7e5802fc5 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInViewCollection.h @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +namespace cvf +{ +class ModelBasicList; +class Transform; +class ScalarMapper; +} // namespace cvf + +class RimSurfaceInView; +class RimSurface; + +class RimSurfaceInViewCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimSurfaceInViewCollection(); + ~RimSurfaceInViewCollection() override; + + void updateFromSurfaceCollection(); + + void appendPartsToModel( cvf::ModelBasicList* surfaceVizModel, cvf::Transform* scaleTransform ); + +private: + caf::PdmFieldHandle* objectToggleField() override; + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue ) override; + + bool hasSurfaceInViewForSurface( const RimSurface* surf ) const; + + caf::PdmField m_isActive; + caf::PdmChildArrayField m_surfacesInView; +}; diff --git a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake index fe24fea64f..03fc9e1c83 100644 --- a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake @@ -65,6 +65,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigFractureGrid.h ${CMAKE_CURRENT_LIST_DIR}/RigFractureCell.h ${CMAKE_CURRENT_LIST_DIR}/RigWellResultPoint.h ${CMAKE_CURRENT_LIST_DIR}/RigWellPathGeometryTools.h +${CMAKE_CURRENT_LIST_DIR}/RigSurface.h ${CMAKE_CURRENT_LIST_DIR}/RigCaseRealizationParameters.h ${CMAKE_CURRENT_LIST_DIR}/RigGeoMechBoreHoleStressCalculator.h ${CMAKE_CURRENT_LIST_DIR}/RigPolyLinesData.h @@ -137,6 +138,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigFractureGrid.cpp ${CMAKE_CURRENT_LIST_DIR}/RigFractureCell.cpp ${CMAKE_CURRENT_LIST_DIR}/RigWellResultPoint.cpp ${CMAKE_CURRENT_LIST_DIR}/RigWellPathGeometryTools.cpp +${CMAKE_CURRENT_LIST_DIR}/RigSurface.cpp ${CMAKE_CURRENT_LIST_DIR}/RigCaseRealizationParameters.cpp ${CMAKE_CURRENT_LIST_DIR}/RigGeoMechBoreHoleStressCalculator.cpp ${CMAKE_CURRENT_LIST_DIR}/RigPolyLinesData.cpp diff --git a/ApplicationCode/ReservoirDataModel/RigSurface.cpp b/ApplicationCode/ReservoirDataModel/RigSurface.cpp new file mode 100644 index 0000000000..9f0d4c6465 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigSurface.cpp @@ -0,0 +1,53 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#include "RigSurface.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigSurface::RigSurface() {} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigSurface::~RigSurface() {} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigSurface::triangleIndices() +{ + return m_triangleIndices; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigSurface::vertices() +{ + return m_vertices; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigSurface::setTriangleData( const std::vector& tringleIndices, const std::vector& vertices ) +{ + m_triangleIndices = tringleIndices; + m_vertices = vertices; +} diff --git a/ApplicationCode/ReservoirDataModel/RigSurface.h b/ApplicationCode/ReservoirDataModel/RigSurface.h new file mode 100644 index 0000000000..e80aefb6e3 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigSurface.h @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "cvfObject.h" +#include "cvfVector3.h" + +#include + +#include +#include + +class RigSurface : public cvf::Object +{ +public: + RigSurface(); + ~RigSurface() override; + + const std::vector& triangleIndices(); + const std::vector& vertices(); + + void setTriangleData( const std::vector& tringleIndices, const std::vector& vertices ); + void addVerticeResult( const QString resultName, const std::vector& resultValues ); + +private: + std::vector m_triangleIndices; + std::vector m_vertices; + std::map> m_verticeResults; +}; diff --git a/ApplicationCode/Resources/ResInsight.qrc b/ApplicationCode/Resources/ResInsight.qrc index 784ec8e3f4..ebd38f59e5 100644 --- a/ApplicationCode/Resources/ResInsight.qrc +++ b/ApplicationCode/Resources/ResInsight.qrc @@ -1,177 +1,179 @@ + 2DMap16x16.png + 2DMapProjection16x16.png + 2DMaps16x16.png + 3DView16x16.png + 3DViewGeoMech16x16.png + 3DWindow24x24.png + AICDValve16x16.png + Annotations16x16.png AppLogo48x48.png - Default.png - NorthViewArrow.png - SouthViewArrow.png - EastViewArrow.png - WestViewArrow.png - UpViewArrow.png - DownViewArrow.png - CellFilter_Values.png + Axes16x16.png + BottomAxis16x16.png + Case48x48.png + Cases16x16.png + CasingDesign16x16.png CellFilter_Range.png + CellFilter_Values.png CellResult.png + Columns1.png + Columns2.png + Columns3.png + Columns4.png + ColumnsUnlimited.png + ComparisonView16x16.png + CompletionsSymbol16x16.png + ControlledView16x16.png + Copy.png + CreateGridCaseGroup16x16.png + CrossSection16x16.png + CrossSections16x16.png + Default.png + DownViewArrow.png + EastViewArrow.png + EclipseInput48x48.png EdgeResult_1.png EdgeResult_2.png - Legend.png - Plus.png - Minus.png - Save.png - Well.png EditableWell.png - WellTargets.png - WellCollection.png - octave.png - OctaveScriptFile16x16.png - PythonScriptFile16x16.png + EnsembleCurveSet16x16.png + EnsembleCurveSets16x16.png + Erase.png + ExportCompletionsSymbol16x16.png + FishBoneGroup16x16.png + FishBoneGroupFromFile16x16.png + FishBoneLateralFromFile16x16.png + FishBones16x16.png + FlowCharPlot16x16.png Folder.png - EclipseInput48x48.png - Cases16x16.png - SummaryCases16x16.png - SummaryEnsemble16x16.png - SummaryEnsemble24x24.png - SummaryGroup16x16.png - CreateGridCaseGroup16x16.png + FormationCollection16x16.png + Formations16x16.png + FractureLayout16x16.png + FractureSymbol16x16.png + FractureTemplate16x16.png + FractureTemplates16x16.png + GeoMechCase24x24.png + GeoMechCase48x48.png + GeoMechCasePropTable24x24.png + GeoMechCaseTime24x24.png + GeoMechCases48x48.png GridCaseGroup16x16.png - ReplaceCase16x16.png + GridModels.png Histogram16x16.png Histograms16x16.png + HoloLensConnect24x24.png + HoloLensDisconnect24x24.png + HoloLensSendContinously24x24.png + HoloLensSendOnce24x24.png + ICDValve16x16.png + ICVValve16x16.png + InfoBox16x16.png + IntersectionBox16x16.png + IntersectionXPlane16x16.png + IntersectionYPlane16x16.png + IntersectionZPlane16x16.png + LGR16x16.png + LasFile16x16.png + LeftAxis16x16.png + Legend.png + LinkView16x16.png + LinkView24x24.png + MainGrid16x16.png + MasterView16x16.png + Minus.png + NorthViewArrow.png + ObservedCSVDataFile16x16.png + ObservedDataFile16x16.png + ObservedRFTDataFile16x16.png + ObservedRSMDataFile16x16.png + OctaveScriptFile16x16.png + Parallel24x24.png + PerforationInterval16x16.png + PerforationIntervals16x16.png + Perspective24x24.png + PlotWindow24x24.png + Plus.png + PolylinesFromFile16x16.png + PythonScriptFile16x16.png + RFTPlot16x16.png + RFTPlots16x16.png + ReachCircle16x16.png + Refresh-32.png + RemoveComparisonView16x16.png + ReplaceCase16x16.png + ReservoirSurface16x16.png + ReservoirSurfaces16x16.png + RightAxis16x16.png + Ruler24x24.png + RulerPoly24x24.png + Save.png + SnapShot.png + SnapShotSave.png + SnapShotSaveViews.png + SouthViewArrow.png + SplitterH.png + SplitterV.png + StepUpDown16x16.png + StepUpDownCorner16x16.png + SummaryCase16x16.png + SummaryCase48x48.png + SummaryCases16x16.png + SummaryCurve16x16.png + SummaryCurveFilter16x16.png + SummaryEnsemble16x16.png + SummaryEnsemble24x24.png + SummaryGroup16x16.png + SummaryPlotLight16x16.png + SummaryPlots16x16.png + SummaryPlotsLight16x16.png + SummaryTemplate16x16.png + SummaryXPlotLight16x16.png + SummaryXPlotsLight16x16.png + Swap.png + TOFAccSatPlot16x16.png + TempLGR16x16.png + TextAnnotation16x16.png + TileWindows24x24.png + ToggleOff16x16.png + ToggleOn16x16.png + ToggleOnOff16x16.png + ToggleOnOthersOff16x16.png + UnLinkView16x16.png + UpViewArrow.png + Well.png + WellAllocLegend16x16.png + WellAllocPie16x16.png + WellAllocPlot16x16.png + WellAllocPlots16x16.png + WellCF16x16.png + WellCollection.png + WellFlowPlot16x16.png + WellLogCurve16x16.png + WellLogPlot16x16.png + WellLogPlots16x16.png + WellLogTrack16x16.png + WellTargetPoint16x16.png + WellTargetPointTangent16x16.png + WellTargets.png + WestViewArrow.png + Window16x16.png ZoomAll16x16.png + calculator.png + chain.png + clipboard.png + disable_lighting_24x24.png + draw_style_WellCellsToRangeFilter_24x24.png + draw_style_faults_24x24.png + draw_style_faults_label_24x24.png draw_style_lines_24x24.png draw_style_meshlines_24x24.png draw_style_meshoutlines_24x24.png draw_style_outlines_24x24.png draw_style_surface_24x24.png - disable_lighting_24x24.png - SnapShot.png - SnapShotSave.png - SnapShotSaveViews.png - draw_style_faults_24x24.png - draw_style_faults_label_24x24.png - Case48x48.png - GridModels.png - draw_style_WellCellsToRangeFilter_24x24.png draw_style_surface_w_fault_mesh_24x24.png - InfoBox16x16.png - GeoMechCase48x48.png - GeoMechCase24x24.png - GeoMechCaseTime24x24.png - GeoMechCasePropTable24x24.png - GeoMechCases48x48.png - chain.png - UnLinkView16x16.png - LinkView16x16.png - LinkView24x24.png - ComparisonView16x16.png - RemoveComparisonView16x16.png - MasterView16x16.png - ControlledView16x16.png - TileWindows24x24.png - Window16x16.png - LasFile16x16.png - WellLogTrack16x16.png - WellLogPlot16x16.png - WellLogPlots16x16.png - WellLogCurve16x16.png - WellCF16x16.png - CrossSection16x16.png - CrossSections16x16.png - Refresh-32.png - SummaryPlotLight16x16.png - SummaryPlots16x16.png - SummaryPlotsLight16x16.png - SummaryCurve16x16.png - SummaryCurveFilter16x16.png - EnsembleCurveSet16x16.png - EnsembleCurveSets16x16.png - SummaryXPlotLight16x16.png - SummaryXPlotsLight16x16.png - ObservedDataFile16x16.png - ObservedRSMDataFile16x16.png - ObservedRFTDataFile16x16.png - ObservedCSVDataFile16x16.png - FormationCollection16x16.png - Formations16x16.png - Parallel24x24.png - Perspective24x24.png - IntersectionBox16x16.png - IntersectionXPlane16x16.png - IntersectionYPlane16x16.png - IntersectionZPlane16x16.png - PlotWindow24x24.png - 3DWindow24x24.png - 3DView16x16.png - 3DViewGeoMech16x16.png - SummaryCase48x48.png - SummaryCase16x16.png + octave.png openFolder24x24.png - clipboard.png - Copy.png - Erase.png - LeftAxis16x16.png - RightAxis16x16.png - BottomAxis16x16.png - Axes16x16.png - FishBones16x16.png - FishBoneGroup16x16.png - FishBoneGroupFromFile16x16.png - FishBoneLateralFromFile16x16.png - PerforationInterval16x16.png - PerforationIntervals16x16.png - CompletionsSymbol16x16.png - WellAllocPlots16x16.png - WellAllocPlot16x16.png - WellFlowPlot16x16.png - WellAllocPie16x16.png - WellAllocLegend16x16.png - RFTPlot16x16.png - RFTPlots16x16.png - FractureLayout16x16.png - FractureSymbol16x16.png - FractureTemplate16x16.png - FractureTemplates16x16.png - TOFAccSatPlot16x16.png - FlowCharPlot16x16.png - SplitterH.png - SplitterV.png - calculator.png statistics.png - WellTargetPoint16x16.png - WellTargetPointTangent16x16.png - HoloLensConnect24x24.png - HoloLensDisconnect24x24.png - HoloLensSendContinously24x24.png - HoloLensSendOnce24x24.png - 2DMap16x16.png - 2DMaps16x16.png - AICDValve16x16.png - ICDValve16x16.png - ICVValve16x16.png - CasingDesign16x16.png - LGR16x16.png - MainGrid16x16.png - TempLGR16x16.png - ToggleOff16x16.png - ToggleOn16x16.png - ToggleOnOff16x16.png - ToggleOnOthersOff16x16.png - ExportCompletionsSymbol16x16.png - StepUpDown16x16.png - StepUpDownCorner16x16.png - TextAnnotation16x16.png - Annotations16x16.png - PolylinesFromFile16x16.png - ReachCircle16x16.png - 2DMapProjection16x16.png - Ruler24x24.png - RulerPoly24x24.png - Swap.png - SummaryTemplate16x16.png - Columns1.png - Columns2.png - Columns3.png - Columns4.png - ColumnsUnlimited.png fs_CellFace.glsl diff --git a/ApplicationCode/Resources/ReservoirSurface16x16.png b/ApplicationCode/Resources/ReservoirSurface16x16.png new file mode 100644 index 0000000000..f4a14dbc53 Binary files /dev/null and b/ApplicationCode/Resources/ReservoirSurface16x16.png differ diff --git a/ApplicationCode/Resources/ReservoirSurfaces16x16.png b/ApplicationCode/Resources/ReservoirSurfaces16x16.png new file mode 100644 index 0000000000..d6bd3d414b Binary files /dev/null and b/ApplicationCode/Resources/ReservoirSurfaces16x16.png differ diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index bd4ae709da..a480e88efb 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -456,6 +456,7 @@ void RiuMainWindow::createMenus() importMenu->addAction( cmdFeatureMgr->action( "RicImportObservedDataInMenuFeature" ) ); importMenu->addAction( cmdFeatureMgr->action( "RicImportObservedFmuDataInMenuFeature" ) ); importMenu->addAction( cmdFeatureMgr->action( "RicImportFormationNamesFeature" ) ); + importMenu->addAction( cmdFeatureMgr->action( "RicImportSurfacesFeature" ) ); QMenu* exportMenu = fileMenu->addMenu( "&Export" ); exportMenu->addAction( cmdFeatureMgr->action( "RicSnapshotViewToFileFeature" ) );