From 7b78c2d35b2d7901fa118930dbe719c62651b00b Mon Sep 17 00:00:00 2001 From: jonjenssen <69144954+jonjenssen@users.noreply.github.com> Date: Thu, 7 Oct 2021 02:12:42 +0200 Subject: [PATCH] GeoMech: show deformations in grid view (#8123) Enable support in geomech view to show grid deformations --- .../GeoMech/GeoMechDataModel/RigFemPart.cpp | 50 +++++---- .../GeoMechDataModel/RigGeoMechCaseData.cpp | 21 ++++ .../GeoMechDataModel/RigGeoMechCaseData.h | 2 + .../RivFemPartGeometryGenerator.cpp | 8 +- .../RivFemPartGeometryGenerator.h | 16 +-- .../RivFemPartPartMgr.cpp | 32 +++++- .../GeoMechVisualization/RivFemPartPartMgr.h | 9 +- .../RivGeoMechPartMgr.cpp | 20 +++- .../GeoMechVisualization/RivGeoMechPartMgr.h | 2 + .../RivGeoMechVizLogic.cpp | 29 ++++- .../GeoMechVisualization/RivGeoMechVizLogic.h | 1 + .../GeoMech/RimGeoMechPart.cpp | 16 +++ .../ProjectDataModel/GeoMech/RimGeoMechPart.h | 9 ++ .../GeoMech/RimGeoMechPartCollection.cpp | 101 +++++++++++++++++- .../GeoMech/RimGeoMechPartCollection.h | 20 ++++ .../GeoMech/RimGeoMechView.cpp | 62 +++++++++++ .../ProjectDataModel/GeoMech/RimGeoMechView.h | 14 ++- 17 files changed, 361 insertions(+), 51 deletions(-) diff --git a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPart.cpp b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPart.cpp index dfb3622891..4a92132d88 100644 --- a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPart.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPart.cpp @@ -404,36 +404,42 @@ float RigFemPart::characteristicElementSize() const { if ( m_characteristicElementSize != std::numeric_limits::infinity() ) return m_characteristicElementSize; - int elmsToAverageCount = 0; - float sumMaxEdgeLength = 0; - for ( int elmIdx = 0; elmIdx < elementCount(); elmIdx++ ) + std::vector elementPriority = { HEX8P, HEX8 }; + + for ( auto elmType : elementPriority ) { - RigElementType eType = this->elementType( elmIdx ); - - if ( ( eType == HEX8P ) || ( eType == HEX8 ) ) + int elmsToAverageCount = 0; + float sumMaxEdgeLength = 0; + for ( int elmIdx = 0; elmIdx < elementCount(); elmIdx++ ) { - const int* elementConn = this->connectivities( elmIdx ); - cvf::Vec3f nodePos0 = this->nodes().coordinates[elementConn[0]]; - cvf::Vec3f nodePos1 = this->nodes().coordinates[elementConn[1]]; - cvf::Vec3f nodePos3 = this->nodes().coordinates[elementConn[3]]; - cvf::Vec3f nodePos4 = this->nodes().coordinates[elementConn[4]]; + RigElementType eType = this->elementType( elmIdx ); - float l1 = ( nodePos1 - nodePos0 ).length(); - float l3 = ( nodePos3 - nodePos0 ).length(); - float l4 = ( nodePos4 - nodePos0 ).length(); + if ( eType == elmType ) + { + const int* elementConn = this->connectivities( elmIdx ); + cvf::Vec3f nodePos0 = this->nodes().coordinates[elementConn[0]]; + cvf::Vec3f nodePos1 = this->nodes().coordinates[elementConn[1]]; + cvf::Vec3f nodePos3 = this->nodes().coordinates[elementConn[3]]; + cvf::Vec3f nodePos4 = this->nodes().coordinates[elementConn[4]]; - float maxLength = l1 > l3 ? l1 : l3; - maxLength = maxLength > l4 ? maxLength : l4; + float l1 = ( nodePos1 - nodePos0 ).length(); + float l3 = ( nodePos3 - nodePos0 ).length(); + float l4 = ( nodePos4 - nodePos0 ).length(); - sumMaxEdgeLength += maxLength; - ++elmsToAverageCount; + float maxLength = l1 > l3 ? l1 : l3; + maxLength = maxLength > l4 ? maxLength : l4; + + sumMaxEdgeLength += maxLength; + ++elmsToAverageCount; + } + } + if ( elmsToAverageCount > 0 ) + { + m_characteristicElementSize = sumMaxEdgeLength / elmsToAverageCount; + break; } } - CVF_ASSERT( elmsToAverageCount ); - - m_characteristicElementSize = sumMaxEdgeLength / elmsToAverageCount; - return m_characteristicElementSize; } diff --git a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp index ab93dd16fb..3f87c9fed8 100644 --- a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp @@ -155,3 +155,24 @@ bool RigGeoMechCaseData::readFemParts( std::string* errorMessage, const std::vec *errorMessage = std::string( "Could not read FEM parts" ); return false; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigGeoMechCaseData::readDisplacements( std::string* errorMessage, + int partId, + int timeStep, + std::vector* displacements ) +{ + CVF_ASSERT( errorMessage ); +#ifdef USE_ODB_API + if ( m_readerInterface.notNull() && m_readerInterface->isOpen() ) + { + m_readerInterface->readDisplacements( partId, timeStep, 1, displacements ); + return true; + } + +#endif + *errorMessage = std::string( "Could not read displacements." ); + return false; +} diff --git a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h index cbb8766d19..741f162744 100644 --- a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h +++ b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h @@ -41,6 +41,8 @@ public: bool open( std::string* errorMessage ); bool readTimeSteps( std::string* errorMessage, std::vector* stepNames ); bool readFemParts( std::string* errorMessage, const std::vector& timeStepFilter = std::vector() ); + bool readDisplacements( std::string* errorMessage, int partId, int timeStep, std::vector* displacements ); + RigFemPartCollection* femParts(); const RigFemPartCollection* femParts() const; diff --git a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.cpp b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.cpp index 970b66ee9e..d4335ec4dc 100644 --- a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.cpp @@ -61,9 +61,9 @@ RivFemPartGeometryGenerator::~RivFemPartGeometryGenerator() /// Generate surface drawable geo from the specified region /// //-------------------------------------------------------------------------------------------------- -ref RivFemPartGeometryGenerator::generateSurface() +ref RivFemPartGeometryGenerator::generateSurface( const std::vector& nodeCoordinates ) { - computeArrays(); + computeArrays( nodeCoordinates ); CVF_ASSERT( m_quadVertices.notNull() ); @@ -126,7 +126,7 @@ ref RivFemPartGeometryGenerator::createOutlineMeshDrawable( double //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivFemPartGeometryGenerator::computeArrays() +void RivFemPartGeometryGenerator::computeArrays( const std::vector& nodeCoordinates ) { std::vector vertices; std::vector& trianglesToElements = m_triangleMapper->triangleToElmIndexMap(); @@ -148,8 +148,6 @@ void RivFemPartGeometryGenerator::computeArrays() trianglesToElements.reserve( estimatedQuadVxCount / 2 ); trianglesToElementFaces.reserve( estimatedQuadVxCount / 2 ); - const std::vector& nodeCoordinates = m_part->nodes().coordinates; - #pragma omp parallel for schedule( dynamic ) for ( int elmIdx = 0; elmIdx < static_cast( m_part->elementCount() ); elmIdx++ ) { diff --git a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.h b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.h index b98595f86b..0426c106d8 100644 --- a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.h +++ b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.h @@ -21,10 +21,13 @@ #include "cvfArray.h" #include "cvfObject.h" +#include "cvfVector3.h" #include "RigFemPart.h" #include "cvfStructGrid.h" +#include + namespace cvf { class DrawableGeo; @@ -77,7 +80,7 @@ public: // Generated geometry - cvf::ref generateSurface(); + cvf::ref generateSurface( const std::vector& nodeCoordinates ); cvf::ref createMeshDrawable(); cvf::ref createOutlineMeshDrawable( double creaseAngle ); @@ -96,7 +99,7 @@ public: const cvf::Vec3d& displayModelOffset ); private: - void computeArrays(); + void computeArrays( const std::vector& nodeCoordinates ); private: // Input @@ -106,11 +109,10 @@ private: // Created arrays cvf::ref m_quadVertices; - // cvf::ref m_triangleVertices; // If needed, we will do it like this, I think - std::vector m_quadVerticesToNodeIdx; - std::vector m_quadVerticesToGlobalElmNodeIdx; - std::vector m_quadVerticesToGlobalElmFaceNodeIdx; - std::vector m_quadVerticesToGlobalElmIdx; + std::vector m_quadVerticesToNodeIdx; + std::vector m_quadVerticesToGlobalElmNodeIdx; + std::vector m_quadVerticesToGlobalElmFaceNodeIdx; + std::vector m_quadVerticesToGlobalElmIdx; // Mappings cvf::ref m_triangleMapper; diff --git a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp index 0e182c8cf0..bed64fcf4c 100644 --- a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp @@ -19,12 +19,15 @@ #include +#include "RivFemPartPartMgr.h" + #include "RivGeoMechPartMgr.h" #include "RiaPreferences.h" #include "RifGeoMechReaderInterface.h" +#include "RigFemPart.h" #include "RigFemPartResultsCollection.h" #include "RigFemScalarResultFrames.h" #include "RigGeoMechCaseData.h" @@ -103,6 +106,33 @@ void RivFemPartPartMgr::setCellVisibility( cvf::UByteArray* cellVisibilities ) generatePartGeometry( m_surfaceGenerator ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivFemPartPartMgr::setDisplacements( bool useDisplacements, + double scalingFactor, + const std::vector& displacements ) +{ + size_t nodeCount = m_part->nodes().coordinates.size(); + m_displacedNodeCoordinates.resize( nodeCount ); + const auto coords = m_part->nodes().coordinates; + + if ( useDisplacements ) + { + for ( size_t i = 0; i < nodeCount; i++ ) + { + m_displacedNodeCoordinates[i] = coords[i] + displacements[i] * scalingFactor; + } + } + else + { + for ( size_t i = 0; i < nodeCount; i++ ) + { + m_displacedNodeCoordinates[i] = coords[i]; + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -113,7 +143,7 @@ void RivFemPartPartMgr::generatePartGeometry( RivFemPartGeometryGenerator& geoBu { m_surfaceFaces = nullptr; // To possibly free memory before adding the new stuff - cvf::ref geo = geoBuilder.generateSurface(); + cvf::ref geo = geoBuilder.generateSurface( m_displacedNodeCoordinates ); if ( geo.notNull() ) { geo->computeNormals(); diff --git a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.h b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.h index e93ed39e4b..56c40cd771 100644 --- a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.h +++ b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.h @@ -20,9 +20,12 @@ #pragma once #include "cvfObject.h" +#include "cvfVector3.h" #include "RivFemPartGeometryGenerator.h" +#include + namespace cvf { class StructGridInterface; @@ -46,12 +49,14 @@ class RigFemPart; class RivFemPartPartMgr : public cvf::Object { public: - explicit RivFemPartPartMgr( const RigFemPart* femPart, cvf::Vec3d displayOffset ); + explicit RivFemPartPartMgr( const RigFemPart* part, cvf::Vec3d displayOffset ); ~RivFemPartPartMgr() override; void setTransform( cvf::Transform* scaleTransform ); void setCellVisibility( cvf::UByteArray* cellVisibilities ); cvf::ref cellVisibility() { return m_cellVisibility; } + void setDisplacements( bool useDisplacements, double scalingFactor, const std::vector& displacements ); + void updateCellColor( cvf::Color4f color ); void updateCellResultColor( size_t timeStepIndex, RimGeoMechCellColors* cellResultColors ); @@ -66,6 +71,8 @@ private: int m_partIdx; cvf::cref m_part; + std::vector m_displacedNodeCoordinates; + cvf::ref m_scaleTransform; float m_opacityLevel; cvf::Color3f m_defaultColor; diff --git a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.cpp b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.cpp index 4f11ed075c..c7c147144c 100644 --- a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.cpp @@ -18,13 +18,16 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RivGeoMechPartMgr.h" -#include "cvfModelBasicList.h" -#include "cvfPart.h" -#include #include "RigFemPartCollection.h" #include "RigGeoMechCaseData.h" +#include "RimGeoMechPartCollection.h" + +#include "cvfModelBasicList.h" +#include "cvfPart.h" +#include + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -59,6 +62,17 @@ void RivGeoMechPartMgr::clearAndSetReservoir( const RigGeoMechCaseData* geoMechC } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivGeoMechPartMgr::updateDisplacements( const RimGeoMechPartCollection* parts, bool showDisplacements, double scaleFactor ) +{ + for ( size_t i = 0; i < m_femPartPartMgrs.size(); i++ ) + { + m_femPartPartMgrs[i]->setDisplacements( showDisplacements, scaleFactor, parts->displacements( (int)i ) ); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.h b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.h index 6cca1e10fa..4bfcd5a797 100644 --- a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.h +++ b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.h @@ -33,6 +33,7 @@ class Transform; class RimGeoMechCellColors; class RigGeoMechCaseData; class RimGeoMechView; +class RimGeoMechPartCollection; //================================================================================================== /// @@ -51,6 +52,7 @@ public: void clearAndSetReservoir( const RigGeoMechCaseData* geoMechCase ); void setTransform( cvf::Transform* scaleTransform ); void setCellVisibility( size_t partIndex, cvf::UByteArray* cellVisibilities ); + void updateDisplacements( const RimGeoMechPartCollection* parts, bool showDisplacements, double scaleFactor ); cvf::ref cellVisibility( size_t partIndex ); diff --git a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp index 6e3f4254f8..ad8005492e 100644 --- a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp @@ -27,6 +27,7 @@ #include "RimCellFilterCollection.h" #include "RimGeoMechCase.h" #include "RimGeoMechCellColors.h" +#include "RimGeoMechPartCollection.h" #include "RimGeoMechPropertyFilterCollection.h" #include "RimGeoMechView.h" #include "RimViewController.h" @@ -126,6 +127,21 @@ void RivGeoMechVizLogic::scheduleGeometryRegen( RivCellSetEnum geometryType ) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivGeoMechVizLogic::scheduleGeometryRegenOfVisiblePartMgrs( int timeStepIndex ) +{ + std::vector visiblePartMgrs = keysToVisiblePartMgrs( timeStepIndex ); + for ( size_t pmIdx = 0; pmIdx < visiblePartMgrs.size(); ++pmIdx ) + { + m_partMgrCache->scheduleRegeneration( visiblePartMgrs[pmIdx] ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- void RivGeoMechVizLogic::scheduleRegenOfDirectlyDependentGeometry( RivCellSetEnum geometryType ) { if ( geometryType == RANGE_FILTERED ) @@ -202,6 +218,10 @@ RivGeoMechPartMgr* RivGeoMechVizLogic::getUpdatedPartMgr( RivGeoMechPartMgrCache partMgrToUpdate->clearAndSetReservoir( caseData ); } + partMgrToUpdate->updateDisplacements( m_geomechView->partsCollection(), + m_geomechView->showDisplacements(), + m_geomechView->displacementScaleFactor() ); + partMgrToUpdate->setTransform( m_geomechView->scaleTransform() ); for ( int femPartIdx = 0; femPartIdx < partCount; ++femPartIdx ) @@ -266,12 +286,11 @@ void RivGeoMechVizLogic::calculateCurrentTotalCellVisibility( cvf::UByteArray* t { if ( !m_geomechView->geoMechCase() ) return; - size_t gridCount = m_geomechView->femParts()->partCount(); - - if ( gridCount == 0 ) return; + int partCount = m_geomechView->femParts()->partCount(); + if ( partCount == 0 ) return; int elmCount = 0; - for ( int i = 0; i < m_geomechView->femParts()->partCount(); i++ ) + for ( int i = 0; i < partCount; i++ ) { RigFemPart* part = m_geomechView->femParts()->part( i ); elmCount += part->elementCount(); @@ -287,7 +306,7 @@ void RivGeoMechVizLogic::calculateCurrentTotalCellVisibility( cvf::UByteArray* t if ( partMgr ) { int elmOffset = 0; - for ( int i = 0; i < m_geomechView->femParts()->partCount(); i++ ) + for ( int i = 0; i < partCount; i++ ) { RigFemPart* part = m_geomechView->femParts()->part( i ); diff --git a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.h b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.h index ff260ebff9..15e66a116b 100644 --- a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.h +++ b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.h @@ -47,6 +47,7 @@ public: void updateCellResultColor( int timeStepIndex, RimGeoMechCellColors* cellResultColors ); void updateStaticCellColors( int timeStepIndex ); void scheduleGeometryRegen( RivCellSetEnum geometryType ); + void scheduleGeometryRegenOfVisiblePartMgrs( int timeStepIndex ); void calculateCurrentTotalCellVisibility( cvf::UByteArray* totalVisibility, int timeStepIndex ); std::vector keysToVisiblePartMgrs( int timeStepIndex ) const; const cvf::ref partMgrCache() const; diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPart.cpp b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPart.cpp index d0fc8aa073..c5740844d2 100644 --- a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPart.cpp +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPart.cpp @@ -79,3 +79,19 @@ void RimGeoMechPart::fieldChangedByUi( const caf::PdmFieldHandle* changedField, if ( ownerView ) ownerView->scheduleCreateDisplayModelAndRedraw(); } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechPart::setDisplacements( std::vector& displacements ) +{ + m_displacements = displacements; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector RimGeoMechPart::displacements() const +{ + return m_displacements; +} diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPart.h b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPart.h index 4e8ff0df81..3ec54802a4 100644 --- a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPart.h +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPart.h @@ -23,6 +23,10 @@ #include "cafPdmField.h" #include "cafPdmObject.h" +#include "cvfVector3.h" + +#include + class RimGeoMechPart : public RimCheckableNamedObject { CAF_PDM_HEADER_INIT; @@ -34,9 +38,14 @@ public: void setPartId( int partId ); int partId() const; + void setDisplacements( std::vector& displacements ); + const std::vector displacements() const; + protected: void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; private: caf::PdmField m_partId; + + std::vector m_displacements; }; diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPartCollection.cpp b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPartCollection.cpp index 6034f34153..7096b6b263 100644 --- a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPartCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPartCollection.cpp @@ -36,6 +36,9 @@ CAF_PDM_SOURCE_INIT( RimGeoMechPartCollection, "GeoMechPartCollection" ); //-------------------------------------------------------------------------------------------------- RimGeoMechPartCollection::RimGeoMechPartCollection() : m_case( nullptr ) + , m_currentDisplacementTimeStep( -1 ) + , m_displacementsUsed( false ) + , m_currentScaleFactor( 1.0 ) { CAF_PDM_InitScriptableObject( "Parts", ":/GeoMechCase24x24.png", "", "" ); @@ -90,6 +93,18 @@ std::vector RimGeoMechPartCollection::parts() const return m_parts.childObjects(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGeoMechPart* RimGeoMechPartCollection::part( int partId ) const +{ + for ( const auto& part : m_parts ) + { + if ( part->partId() == partId ) return part; + } + return nullptr; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -103,10 +118,88 @@ bool RimGeoMechPartCollection::shouldBeVisibleInTree() const //-------------------------------------------------------------------------------------------------- bool RimGeoMechPartCollection::isPartEnabled( int partId ) const { - for ( const auto& part : m_parts ) - { - if ( part->partId() == partId ) return part->isChecked(); - } + RimGeoMechPart* thepart = part( partId ); + if ( thepart ) return thepart->isChecked(); return false; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechPartCollection::setCurrentDisplacementSettings( int currentTimeStep, bool showDisplacement, double scaleFactor ) +{ + m_currentDisplacementTimeStep = currentTimeStep; + m_displacementsUsed = showDisplacement; + m_currentScaleFactor = scaleFactor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimGeoMechPartCollection::currentDisplacementTimeStep() const +{ + return m_currentDisplacementTimeStep; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechPartCollection::setDisplacementsForPart( int partId, std::vector displacements ) +{ + RimGeoMechPart* thepart = part( partId ); + if ( thepart ) thepart->setDisplacements( displacements ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector RimGeoMechPartCollection::displacements( int partId ) const +{ + RimGeoMechPart* thepart = part( partId ); + if ( thepart ) return thepart->displacements(); + + return std::vector(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimGeoMechPartCollection::isDisplacementsUsed() const +{ + return m_displacementsUsed; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimGeoMechPartCollection::shouldRebuildPartVisualization( int currentTimeStep, bool showDisplacement, double scaleFactor ) +{ + // if show flag has changed, we need to rebuild grid viz. + bool retVal = m_displacementsUsed != showDisplacement; + + // if scaling or timestep has changed, we need to rebuild grid if the displacement should be visible + if ( showDisplacement ) + retVal = retVal || ( m_currentDisplacementTimeStep != currentTimeStep ) || + ( std::abs( m_currentScaleFactor - scaleFactor ) > 0.0001 ); + + return retVal; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimGeoMechPartCollection::shouldReloadDisplacements( int currentTimeStep, bool showDisplacement, double scaleFactor ) +{ + // no need to reload something we are not showing + if ( !showDisplacement ) return false; + + // if we have no displacements at all, we need to reload. + for ( const auto& part : m_parts ) + { + if ( part->displacements().size() == 0 ) return true; + } + + // if timestep has changed we need to reload + return m_currentDisplacementTimeStep != currentTimeStep; +} diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPartCollection.h b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPartCollection.h index 78636d0ca2..f5f759603e 100644 --- a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPartCollection.h +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPartCollection.h @@ -21,6 +21,10 @@ #include "cafPdmField.h" #include "cafPdmObject.h" +#include "cvfVector3.h" + +#include + class RimGeoMechPart; class RimGeoMechCase; @@ -34,13 +38,29 @@ public: void syncWithCase( RimGeoMechCase* geoCase ); + bool shouldRebuildPartVisualization( int currentTimeStep, bool showDisplacement, double scaleFactor ); + bool shouldReloadDisplacements( int currentTimeStep, bool showDisplacement, double scaleFactor ); bool shouldBeVisibleInTree() const; bool isPartEnabled( int partId ) const; + void setDisplacementsForPart( int partId, std::vector displacements ); + const std::vector displacements( int partId ) const; + + void setCurrentDisplacementSettings( int currentTimeStep, bool showDisplacement, double scaleFactor ); + bool isDisplacementsUsed() const; + int currentDisplacementTimeStep() const; + double currentScaleFactor() const; + std::vector parts() const; private: + RimGeoMechPart* part( int partId ) const; + caf::PdmChildArrayField m_parts; RimGeoMechCase* m_case; + + int m_currentDisplacementTimeStep; + double m_currentScaleFactor; + bool m_displacementsUsed; }; diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.cpp b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.cpp index 7777e39ba5..a6a4c59f8d 100644 --- a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.cpp +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.cpp @@ -102,6 +102,9 @@ RimGeoMechView::RimGeoMechView( void ) m_partsCollection = new RimGeoMechPartCollection(); m_partsCollection.uiCapability()->setUiHidden( true ); + CAF_PDM_InitField( &m_showDisplacement, "ShowDisplacement", false, "Show Displacement", "", "", "" ); + CAF_PDM_InitField( &m_displacementScaling, "DisplacementScaling", 1.0, "Scaling Factor", "", "", "" ); + m_scaleTransform = new cvf::Transform(); m_vizLogic = new RivGeoMechVizLogic( this ); m_tensorPartMgr = new RivTensorResultPartMgr( this ); @@ -257,6 +260,8 @@ void RimGeoMechView::onCreateDisplayModel() theParts->part( i )->setEnabled( m_partsCollection()->isPartEnabled( i ) ); } + updateElementDisplacements(); + // Remove all existing animation frames from the viewer. // The parts are still cached in the RivReservoir geometry and friends @@ -343,6 +348,31 @@ RimPropertyFilterCollection* RimGeoMechView::nativePropertyFilterCollection() return m_propertyFilterCollection(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechView::updateElementDisplacements() +{ + if ( !m_partsCollection->shouldRebuildPartVisualization( m_currentTimeStep, m_showDisplacement, m_displacementScaling ) ) + return; + + if ( m_partsCollection->shouldReloadDisplacements( m_currentTimeStep, m_showDisplacement, m_displacementScaling ) ) + { + for ( auto part : m_partsCollection->parts() ) + { + std::string errmsg; + std::vector displacements; + m_geomechCase->geoMechData()->readDisplacements( &errmsg, part->partId(), m_currentTimeStep, &displacements ); + part->setDisplacements( displacements ); + } + } + // store current settings so that we know if we need to rebuild later if any of them changes + m_partsCollection->setCurrentDisplacementSettings( m_currentTimeStep, m_showDisplacement, m_displacementScaling ); + + // tell geometry generator to regenerate grid + m_vizLogic->scheduleGeometryRegenOfVisiblePartMgrs( m_currentTimeStep ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -350,6 +380,8 @@ void RimGeoMechView::onUpdateDisplayModelForCurrentTimeStep() { onUpdateLegends(); + updateElementDisplacements(); + if ( this->isTimeStepDependentDataVisibleInThisOrComparisonView() ) { if ( nativeOrOverrideViewer() ) @@ -800,6 +832,11 @@ bool RimGeoMechView::isTimeStepDependentDataVisible() const return true; } + if ( ( m_showDisplacement ) || m_partsCollection->isDisplacementsUsed() ) + { + return true; + } + return false; } @@ -819,6 +856,11 @@ void RimGeoMechView::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& newValue ) { RimGridView::fieldChangedByUi( changedField, oldValue, newValue ); + + if ( ( changedField == &m_showDisplacement ) || ( ( changedField == &m_displacementScaling ) && m_showDisplacement() ) ) + { + this->createDisplayModelAndRedraw(); + } } //-------------------------------------------------------------------------------------------------- @@ -955,6 +997,10 @@ void RimGeoMechView::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& caf::PdmUiGroup* nameGroup = uiOrdering.addNewGroup( "View Name" ); nameConfig()->uiOrdering( uiConfigName, *nameGroup ); + + auto displacementGroup = uiOrdering.addNewGroup( "Displacements" ); + displacementGroup->add( &m_showDisplacement ); + displacementGroup->add( &m_displacementScaling ); } //-------------------------------------------------------------------------------------------------- @@ -1002,3 +1048,19 @@ const RimGeoMechPartCollection* RimGeoMechView::partsCollection() const { return m_partsCollection(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimGeoMechView::displacementScaleFactor() const +{ + return m_displacementScaling; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimGeoMechView::showDisplacements() const +{ + return m_showDisplacement; +} diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.h b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.h index 6a2cb0e750..1e63cd01a6 100644 --- a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.h +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.h @@ -37,6 +37,7 @@ class Rim3dOverlayInfoConfig; class RimCellRangeFilterCollection; class RimGeoMechCase; class RimGeoMechCellColors; +class RimGeoMechPartCollection; class RimGeoMechPropertyFilterCollection; class RimGeoMechResultDefinition; class RimRegularLegendConfig; @@ -105,6 +106,9 @@ public: void convertCameraPositionFromOldProjectFiles(); + double displacementScaleFactor() const; + bool showDisplacements() const; + protected: void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override; @@ -133,14 +137,18 @@ private: void updateTensorLegendTextAndRanges( RimRegularLegendConfig* legendConfig, int timeStepIndex ); + void updateElementDisplacements(); + caf::PdmChildField m_tensorResults; caf::PdmChildField m_propertyFilterCollection; caf::PdmPointer m_overridePropertyFilterCollection; caf::PdmChildField m_partsCollection; + caf::PdmPointer m_geomechCase; + caf::PdmField m_showDisplacement; + caf::PdmField m_displacementScaling; - caf::PdmPointer m_geomechCase; - cvf::ref m_vizLogic; - cvf::ref m_scaleTransform; + cvf::ref m_vizLogic; + cvf::ref m_scaleTransform; cvf::ref m_tensorPartMgr; };