diff --git a/ApplicationCode/Commands/SurfaceCommands/RicNewGridCaseSurfaceFeature.cpp b/ApplicationCode/Commands/SurfaceCommands/RicNewGridCaseSurfaceFeature.cpp index 091f744ae5..4e24f48c67 100644 --- a/ApplicationCode/Commands/SurfaceCommands/RicNewGridCaseSurfaceFeature.cpp +++ b/ApplicationCode/Commands/SurfaceCommands/RicNewGridCaseSurfaceFeature.cpp @@ -18,8 +18,6 @@ #include "RicNewGridCaseSurfaceFeature.h" -#include "RiaApplication.h" - #include "RimOilField.h" #include "RimProject.h" #include "RimSurface.h" @@ -44,11 +42,7 @@ bool RicNewGridSurfaceFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicNewGridSurfaceFeature::onActionTriggered( bool isChecked ) { - RiaApplication* app = RiaApplication::instance(); - - // Find or create the SurfaceCollection - - RimProject* proj = RiaApplication::instance()->project(); + RimProject* proj = RimProject::current(); RimSurfaceCollection* surfColl = proj->activeOilField()->surfaceCollection(); if ( !surfColl ) diff --git a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp index c06b1b8462..6f8de8f28e 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp @@ -999,6 +999,8 @@ void RimEclipseView::onLoadDataAndUpdate() this->m_wellCollection->scaleWellDisks(); + this->m_surfaceCollection->loadData(); + scheduleReservoirGridGeometryRegen(); m_simWellsPartManager->clearGeometryCache(); diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimFileSurface.cpp b/ApplicationCode/ProjectDataModel/Surfaces/RimFileSurface.cpp index decdfa91b4..a724bb69cc 100644 --- a/ApplicationCode/ProjectDataModel/Surfaces/RimFileSurface.cpp +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimFileSurface.cpp @@ -53,6 +53,8 @@ void RimFileSurface::setSurfaceFilePath( const QString& filePath ) { setUserDescription( QFileInfo( filePath ).fileName() ); } + + clearCachedNativeFileData(); } //-------------------------------------------------------------------------------------------------- @@ -66,7 +68,7 @@ QString RimFileSurface::surfaceFilePath() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimFileSurface::loadData() +bool RimFileSurface::onLoadData() { return updateSurfaceDataFromFile(); } @@ -82,6 +84,7 @@ void RimFileSurface::fieldChangedByUi( const caf::PdmFieldHandle* changedField, if ( changedField == &m_surfaceDefinitionFilePath ) { + clearCachedNativeFileData(); updateSurfaceDataFromFile(); RimSurfaceCollection* surfColl; @@ -95,11 +98,46 @@ void RimFileSurface::fieldChangedByUi( const caf::PdmFieldHandle* changedField, //-------------------------------------------------------------------------------------------------- bool RimFileSurface::updateSurfaceDataFromFile() { - QString filePath = this->surfaceFilePath(); + bool result = true; + if ( m_vertices.empty() ) + { + result = loadDataFromFile(); + } - std::vector tringleIndices; + std::vector vertices{m_vertices}; + std::vector tringleIndices{m_tringleIndices}; + + auto surface = new RigSurface; + if ( !vertices.empty() && !tringleIndices.empty() ) + { + RimSurface::applyDepthOffsetIfNeeded( &vertices ); + + surface->setTriangleData( tringleIndices, vertices ); + } + + setSurfaceData( surface ); + + return result; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFileSurface::clearCachedNativeFileData() +{ + m_vertices.clear(); + m_tringleIndices.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimFileSurface::loadDataFromFile() +{ std::vector vertices; + std::vector tringleIndices; + QString filePath = this->surfaceFilePath(); if ( filePath.endsWith( "ptl", Qt::CaseInsensitive ) ) { auto surface = RifSurfaceReader::readPetrelFile( filePath ); @@ -115,15 +153,10 @@ bool RimFileSurface::updateSurfaceDataFromFile() tringleIndices = surface.second; } - if ( !vertices.empty() && !tringleIndices.empty() ) - { - auto surface = new RigSurface(); - surface->setTriangleData( tringleIndices, vertices ); + m_vertices = vertices; + m_tringleIndices = tringleIndices; - setSurfaceData( surface ); + if ( vertices.empty() || tringleIndices.empty() ) return false; - return true; - } - - return false; + return true; } diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimFileSurface.h b/ApplicationCode/ProjectDataModel/Surfaces/RimFileSurface.h index b92a1b5eec..8b966d0614 100644 --- a/ApplicationCode/ProjectDataModel/Surfaces/RimFileSurface.h +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimFileSurface.h @@ -31,13 +31,18 @@ public: void setSurfaceFilePath( const QString& filePath ); QString surfaceFilePath(); - bool loadData() override; + bool onLoadData() override; private: bool updateSurfaceDataFromFile(); + void clearCachedNativeFileData(); + bool loadDataFromFile(); private: void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; caf::PdmField m_surfaceDefinitionFilePath; + + std::vector m_tringleIndices; + std::vector m_vertices; }; diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimGridCaseSurface.cpp b/ApplicationCode/ProjectDataModel/Surfaces/RimGridCaseSurface.cpp index f6ce3a8714..f0a4def1be 100644 --- a/ApplicationCode/ProjectDataModel/Surfaces/RimGridCaseSurface.cpp +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimGridCaseSurface.cpp @@ -50,7 +50,7 @@ RimGridCaseSurface::RimGridCaseSurface() "", "" ); - CAF_PDM_InitField( &m_sliceIndex, "SliceIndex", 0, "Slice Index", "", "", "" ); + CAF_PDM_InitField( &m_sliceIndex, "SliceIndex", 1, "Slice Index", "", "", "" ); m_sliceIndex.uiCapability()->setUiEditorTypeName( caf::PdmUiSliderEditor::uiEditorTypeName() ); } @@ -72,7 +72,7 @@ void RimGridCaseSurface::setCase( RimCase* sourceCase ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimGridCaseSurface::loadData() +bool RimGridCaseSurface::onLoadData() { return updateSurfaceDataFromGridCase(); } @@ -130,8 +130,11 @@ void RimGridCaseSurface::fieldChangedByUi( const caf::PdmFieldHandle* changedFie const QVariant& oldValue, const QVariant& newValue ) { + RimSurface::fieldChangedByUi( changedField, oldValue, newValue ); + if ( changedField == &m_case || changedField == &m_sliceDirection || changedField == &m_sliceIndex ) { + clearNativeGridData(); updateSurfaceDataFromGridCase(); RimSurfaceCollection* surfColl; @@ -141,12 +144,10 @@ void RimGridCaseSurface::fieldChangedByUi( const caf::PdmFieldHandle* changedFie } //-------------------------------------------------------------------------------------------------- -/// Returns false for fatal failure +/// //-------------------------------------------------------------------------------------------------- -bool RimGridCaseSurface::updateSurfaceDataFromGridCase() +void RimGridCaseSurface::extractDataFromGrid() { - RigSurface* surfaceData = nullptr; - std::vector tringleIndices; std::vector vertices; @@ -171,48 +172,72 @@ bool RimGridCaseSurface::updateSurfaceDataFromGridCase() RimEclipseCase* eclCase = dynamic_cast( m_case() ); if ( eclCase && eclCase->mainGrid() ) { + const RigMainGrid* grid = eclCase->mainGrid(); + + size_t zeroBasedLayerIndex = static_cast( m_sliceIndex - 1 ); + for ( size_t i = 0; i < grid->cellCountI(); i++ ) { - const RigMainGrid* grid = eclCase->mainGrid(); - - size_t k = m_sliceIndex; - for ( size_t i = 0; i < grid->cellCountI(); i++ ) + for ( size_t j = 0; j < grid->cellCountJ(); j++ ) { - for ( size_t j = 0; j < grid->cellCountJ(); j++ ) + size_t cellIndex = grid->cellIndexFromIJK( i, j, zeroBasedLayerIndex ); + + if ( grid->cell( cellIndex ).isInvalid() ) continue; + + cvf::Vec3d cornerVerts[8]; + grid->cellCornerVertices( cellIndex, cornerVerts ); + + cvf::ubyte faceConn[4]; + grid->cellFaceVertexIndices( faceType, faceConn ); + + cvf::uint triangleIndex = static_cast( vertices.size() ); + + for ( int n = 0; n < 4; n++ ) { - size_t cellIndex = grid->cellIndexFromIJK( i, j, k ); - - if ( grid->cell( cellIndex ).isInvalid() ) continue; - - cvf::Vec3d cornerVerts[8]; - grid->cellCornerVertices( cellIndex, cornerVerts ); - - cvf::ubyte faceConn[4]; - grid->cellFaceVertexIndices( faceType, faceConn ); - - cvf::uint triangleIndex = static_cast( vertices.size() ); - - for ( int n = 0; n < 4; n++ ) - { - vertices.push_back( cornerVerts[faceConn[n]] ); - } - - tringleIndices.push_back( triangleIndex + 0 ); - tringleIndices.push_back( triangleIndex + 1 ); - tringleIndices.push_back( triangleIndex + 2 ); - - tringleIndices.push_back( triangleIndex + 0 ); - tringleIndices.push_back( triangleIndex + 2 ); - tringleIndices.push_back( triangleIndex + 3 ); + vertices.push_back( cornerVerts[faceConn[n]] ); } + + tringleIndices.push_back( triangleIndex + 0 ); + tringleIndices.push_back( triangleIndex + 1 ); + tringleIndices.push_back( triangleIndex + 2 ); + + tringleIndices.push_back( triangleIndex + 0 ); + tringleIndices.push_back( triangleIndex + 2 ); + tringleIndices.push_back( triangleIndex + 3 ); } } } } + m_vertices = vertices; + m_tringleIndices = tringleIndices; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridCaseSurface::clearNativeGridData() +{ + m_vertices.clear(); + m_tringleIndices.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// Returns false for fatal failure +//-------------------------------------------------------------------------------------------------- +bool RimGridCaseSurface::updateSurfaceDataFromGridCase() +{ + if ( m_vertices.empty() || m_tringleIndices.empty() ) + { + extractDataFromGrid(); + } + + RigSurface* surfaceData = nullptr; + + std::vector tringleIndices{m_tringleIndices}; + std::vector vertices{m_vertices}; + if ( !tringleIndices.empty() ) { - surfaceData = new RigSurface; - { // Modify the z-value slightly to avoid geometrical numerical issues when the surface intersects exactly at // the cell face @@ -234,12 +259,13 @@ bool RimGridCaseSurface::updateSurfaceDataFromGridCase() offset.z() += delta; } - for ( auto& v : vertices ) - { - v += offset; - } + // Include the potential depth offset in the base class + offset.z() += depthOffset(); + + RimSurface::applyDepthOffset( offset, &vertices ); } + surfaceData = new RigSurface; surfaceData->setTriangleData( tringleIndices, vertices ); } diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimGridCaseSurface.h b/ApplicationCode/ProjectDataModel/Surfaces/RimGridCaseSurface.h index 3e5dc221c9..b7adc74f28 100644 --- a/ApplicationCode/ProjectDataModel/Surfaces/RimGridCaseSurface.h +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimGridCaseSurface.h @@ -36,7 +36,7 @@ public: void setCase( RimCase* sourceCase ); - bool loadData() override; + bool onLoadData() override; protected: QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, @@ -50,8 +50,14 @@ private: bool updateSurfaceDataFromGridCase(); void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; + void extractDataFromGrid(); + void clearNativeGridData(); + private: caf::PdmPtrField m_case; caf::PdmField> m_sliceDirection; caf::PdmField m_sliceIndex; + + std::vector m_tringleIndices; + std::vector m_vertices; }; diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimSurface.cpp b/ApplicationCode/ProjectDataModel/Surfaces/RimSurface.cpp index d95637795f..52d6b16d3a 100644 --- a/ApplicationCode/ProjectDataModel/Surfaces/RimSurface.cpp +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimSurface.cpp @@ -24,9 +24,9 @@ #include "RifSurfaceReader.h" -#include +#include "cafPdmUiDoubleSliderEditor.h" -CAF_PDM_SOURCE_INIT( RimSurface, "Surface" ); +CAF_PDM_ABSTRACT_SOURCE_INIT( RimSurface, "Surface" ); //-------------------------------------------------------------------------------------------------- /// @@ -37,6 +37,8 @@ RimSurface::RimSurface() CAF_PDM_InitFieldNoDefault( &m_userDescription, "SurfaceUserDecription", "Name", "", "", "" ); CAF_PDM_InitField( &m_color, "SurfaceColor", cvf::Color3f( 0.5f, 0.3f, 0.2f ), "Color", "", "", "" ); + + CAF_PDM_InitField( &m_depthOffset, "DepthOffset", 0.0, "Depth Offset", "", "", "" ); } //-------------------------------------------------------------------------------------------------- @@ -73,9 +75,12 @@ QString RimSurface::userDescription() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimSurface::loadData() +void RimSurface::loadDataIfRequired() { - return true; + if ( m_surfaceData.isNull() ) + { + onLoadData(); + } } //-------------------------------------------------------------------------------------------------- @@ -94,6 +99,45 @@ void RimSurface::setSurfaceData( RigSurface* surface ) m_surfaceData = surface; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurface::applyDepthOffsetIfNeeded( std::vector* vertices ) const +{ + double epsilon = 1.0e-10; + + if ( std::fabs( m_depthOffset ) > epsilon ) + { + cvf::Vec3d offset = cvf::Vec3d::ZERO; + + offset.z() += m_depthOffset; + + RimSurface::applyDepthOffset( offset, vertices ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimSurface::depthOffset() const +{ + return m_depthOffset; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurface::applyDepthOffset( const cvf::Vec3d& offset, std::vector* vertices ) +{ + if ( vertices ) + { + for ( auto& v : *vertices ) + { + v += offset; + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -115,7 +159,24 @@ caf::PdmFieldHandle* RimSurface::userDescriptionField() //-------------------------------------------------------------------------------------------------- void RimSurface::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) { + bool updateViews = false; + if ( changedField == &m_color ) + { + updateViews = true; + } + else if ( changedField == &m_userDescription ) + { + this->updateConnectedEditors(); + } + else if ( changedField == &m_depthOffset ) + { + this->onLoadData(); + + updateViews = true; + } + + if ( updateViews ) { RimSurfaceCollection* surfColl; this->firstAncestorOrThisOfTypeAsserted( surfColl ); diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimSurface.h b/ApplicationCode/ProjectDataModel/Surfaces/RimSurface.h index 39042ac212..d8dc7bd9c6 100644 --- a/ApplicationCode/ProjectDataModel/Surfaces/RimSurface.h +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimSurface.h @@ -20,10 +20,13 @@ #include "cafPdmField.h" #include "cafPdmObject.h" -#include "cvfObject.h" - #include "cafPdmFieldCvfColor.h" +#include "cvfObject.h" +#include "cvfVector3.h" + +#include + class RigSurface; class RimSurface : public caf::PdmObject @@ -41,19 +44,27 @@ public: QString userDescription(); - virtual bool loadData(); + void loadDataIfRequired(); protected: void setUserDescription( const QString& description ); void setSurfaceData( RigSurface* surface ); + void applyDepthOffsetIfNeeded( std::vector* vertices ) const; + double depthOffset() const; + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; + static void applyDepthOffset( const cvf::Vec3d& offset, std::vector* vertices ); + + virtual bool onLoadData() = 0; + private: caf::PdmFieldHandle* userDescriptionField() override; caf::PdmField m_userDescription; caf::PdmField m_color; + caf::PdmField m_depthOffset; cvf::ref m_surfaceData; }; diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceCollection.cpp b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceCollection.cpp index f4f1c7a116..b591316664 100644 --- a/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceCollection.cpp @@ -98,7 +98,7 @@ RimSurface* RimSurfaceCollection::importSurfacesFromFiles( const QStringList& fi newSurface->setSurfaceFilePath( newFileName ); newSurface->setColor( newColor ); - if ( !newSurface->loadData() ) + if ( !newSurface->onLoadData() ) { delete newSurface; errorMessages += newFileName + "\n"; @@ -161,10 +161,7 @@ void RimSurfaceCollection::loadData() { for ( auto surf : m_surfaces ) { - if ( !surf->loadData() ) - { - // Error: could not open the surface file surf->surfaceFilePath(); - } + surf->loadDataIfRequired(); } } diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInViewCollection.cpp b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInViewCollection.cpp index b957895a71..112d94cff8 100644 --- a/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInViewCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInViewCollection.cpp @@ -23,6 +23,7 @@ #include "RimIntersectionResultDefinition.h" #include "RimOilField.h" #include "RimProject.h" +#include "RimSurface.h" #include "RimSurfaceCollection.h" #include "RimSurfaceInView.h" @@ -94,6 +95,20 @@ void RimSurfaceInViewCollection::updateFromSurfaceCollection() this->updateConnectedEditors(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurfaceInViewCollection::loadData() +{ + for ( RimSurfaceInView* surf : m_surfacesInView ) + { + if ( surf->isActive() && surf->surface() ) + { + surf->surface()->loadDataIfRequired(); + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInViewCollection.h b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInViewCollection.h index 3c83bf3cf9..586f386330 100644 --- a/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInViewCollection.h +++ b/ApplicationCode/ProjectDataModel/Surfaces/RimSurfaceInViewCollection.h @@ -40,6 +40,7 @@ public: ~RimSurfaceInViewCollection() override; void updateFromSurfaceCollection(); + void loadData(); void appendPartsToModel( cvf::ModelBasicList* surfaceVizModel, cvf::Transform* scaleTransform ); void updateCellResultColor( bool hasGeneralCellResult, size_t timeStepIndex );