diff --git a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemNativeVisibleCellsStatCalc.h b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemNativeVisibleCellsStatCalc.h index f1ab9ecc52..004d4524d0 100644 --- a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemNativeVisibleCellsStatCalc.h +++ b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemNativeVisibleCellsStatCalc.h @@ -115,6 +115,8 @@ private: const std::vector& values = m_resultsData->resultValues( m_resVarAddr, pIdx, (int)timeStepIndex ); int elmCount = part->elementCount(); + if ( values.empty() ) continue; + for ( int elmIdx = 0; elmIdx < elmCount; ++elmIdx ) { if ( !( *m_cellVisibilities )[elmIdx] ) continue; diff --git a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPart.cpp b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPart.cpp index 0eba83ab5c..dfb3622891 100644 --- a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPart.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPart.cpp @@ -29,6 +29,7 @@ RigFemPart::RigFemPart() : m_elementPartId( -1 ) , m_characteristicElementSize( std::numeric_limits::infinity() ) + , m_enabled( true ) { } @@ -409,7 +410,7 @@ float RigFemPart::characteristicElementSize() const { RigElementType eType = this->elementType( elmIdx ); - if ( eType == HEX8P ) + if ( ( eType == HEX8P ) || ( eType == HEX8 ) ) { const int* elementConn = this->connectivities( elmIdx ); cvf::Vec3f nodePos0 = this->nodes().coordinates[elementConn[0]]; @@ -562,3 +563,35 @@ bool RigFemPart::isHexahedron( size_t elementIdx ) const RigElementType elType = elementType( elementIdx ); return elType == HEX8 || elType == HEX8P; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFemPart::setName( std::string name ) +{ + m_name = name; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::string RigFemPart::name() const +{ + return m_name; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFemPart::setEnabled( bool enable ) +{ + m_enabled = enable; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigFemPart::enabled() const +{ + return m_enabled; +} diff --git a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPart.h b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPart.h index 3d3c2e54b5..3ec2c7b986 100644 --- a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPart.h +++ b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPart.h @@ -27,6 +27,7 @@ #include "cvfBoundingBox.h" #include "cvfObject.h" #include "cvfVector3.h" +#include #include class RigFemPartGrid; @@ -92,8 +93,16 @@ public: const RigFemPartGrid* getOrCreateStructGrid() const; const std::vector& elementIdxToId() const; + void setName( std::string name ); + std::string name() const; + + void setEnabled( bool enable ); + bool enabled() const; + private: - int m_elementPartId; + int m_elementPartId; + std::string m_name; + bool m_enabled; std::vector m_elementId; std::vector m_elementTypes; diff --git a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartGrid.cpp b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartGrid.cpp index 8783b36ffe..27f91354b0 100644 --- a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartGrid.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartGrid.cpp @@ -74,8 +74,6 @@ void RigFemPartGrid::generateStructGridData() int elmIdxForIJK_000 = findElmIdxForIJK000(); - CVF_ASSERT( elmIdxForIJK_000 != -1 ); // Debug. When we have run enough tests, remove - if ( elmIdxForIJK_000 == -1 ) return; // Find the IJK faces based on the corner cell diff --git a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorMudWeightWindow.cpp b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorMudWeightWindow.cpp index f824ae99f4..7fc4f63fe6 100644 --- a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorMudWeightWindow.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorMudWeightWindow.cpp @@ -172,8 +172,11 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate( int frameCount = stressDataFrames->frameCount(); for ( int fIdx = 0; fIdx < frameCount; ++fIdx ) { - const std::vector& porFrameData = porePressureDataFrames->frameData( fIdx ); + const std::vector& porFrameData = porePressureDataFrames->frameData( fIdx ); + if ( porFrameData.empty() ) continue; + const std::vector& initialPorFrameData = porePressureDataFrames->frameData( 0 ); + if ( initialPorFrameData.empty() ) continue; const std::vector& stressFrameData = stressDataFrames->frameData( fIdx ); const std::vector& obg0FrameData = obg0DataFrames->frameData( 0 ); diff --git a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorNormalST.cpp b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorNormalST.cpp index 2f0155f4f1..a82c5b23de 100644 --- a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorNormalST.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorNormalST.cpp @@ -86,6 +86,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorNormalST::calculate( int { const std::vector& srcSFrameData = srcSDataFrames->frameData( fIdx ); const std::vector& srcPORFrameData = srcPORDataFrames->frameData( fIdx ); + if ( srcPORFrameData.empty() ) continue; int elementCount = femPart->elementCount(); diff --git a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorNormalized.cpp b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorNormalized.cpp index fb763f5098..9725190e95 100644 --- a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorNormalized.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorNormalized.cpp @@ -100,7 +100,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorNormalized::calculate( int const RigFemPart* femPart = m_resultCollection->parts()->part( partIndex ); const RigFemPartGrid* femPartGrid = femPart->getOrCreateStructGrid(); - float inf = std::numeric_limits::infinity(); + const float inf = std::numeric_limits::infinity(); int elmNodeCount = femPart->elementCount(); const std::vector& nodeCoords = femPart->nodes().coordinates; @@ -108,6 +108,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorNormalized::calculate( int for ( int fIdx = 0; fIdx < frameCount; ++fIdx ) { const std::vector& porFrameData = porDataFrames->frameData( fIdx ); + if ( porFrameData.empty() ) continue; const std::vector& srcFrameData = srcDataFrames->frameData( fIdx ); std::vector& dstFrameData = dstDataFrames->frameData( fIdx ); diff --git a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorShearSlipIndicator.cpp b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorShearSlipIndicator.cpp index 8326522b8f..298ab3d953 100644 --- a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorShearSlipIndicator.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorShearSlipIndicator.cpp @@ -94,8 +94,10 @@ RigFemScalarResultFrames* for ( int fIdx = 0; fIdx < frameCount; ++fIdx ) { const std::vector& porFrameData = porePressureDataFrames->frameData( fIdx ); + if ( porFrameData.empty() ) continue; const std::vector& stressFrameData = stressDataFrames->frameData( fIdx ); + if ( stressFrameData.empty() ) continue; std::vector& shearSlipIndicatorFrameData = shearSlipIndicatorFrames->frameData( fIdx ); diff --git a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorStressGradients.cpp b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorStressGradients.cpp index fa3788c3bf..83a66c5c39 100644 --- a/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorStressGradients.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultCalculatorStressGradients.cpp @@ -120,6 +120,8 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorStressGradients::calculate( std::vector& dstFrameDataY = dataFramesY->frameData( fIdx ); std::vector& dstFrameDataZ = dataFramesZ->frameData( fIdx ); size_t valCount = inputData.size(); + if ( valCount == 0 ) continue; + dstFrameDataX.resize( valCount ); dstFrameDataY.resize( valCount ); dstFrameDataZ.resize( valCount ); diff --git a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp index 719ae5f371..13ad859b75 100644 --- a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp @@ -89,7 +89,7 @@ void RivFemElmVisibilityCalculator::computeRangeVisibility( cvf::UByteArray* /// //-------------------------------------------------------------------------------------------------- void RivFemElmVisibilityCalculator::computePropertyVisibility( cvf::UByteArray* cellVisibility, - const RigFemPart* grid, + const RigFemPart* part, int timeStepIndex, const cvf::UByteArray* rangeFilterVisibility, RimGeoMechPropertyFilterCollection* propFilterColl ) @@ -98,12 +98,12 @@ void RivFemElmVisibilityCalculator::computePropertyVisibility( cvf::UByteArray* CVF_ASSERT( rangeFilterVisibility != nullptr ); CVF_ASSERT( propFilterColl != nullptr ); - CVF_ASSERT( grid->elementCount() > 0 ); - CVF_ASSERT( rangeFilterVisibility->size() == static_cast( grid->elementCount() ) ); + CVF_ASSERT( part->elementCount() > 0 ); + CVF_ASSERT( rangeFilterVisibility->size() == static_cast( part->elementCount() ) ); // Copy if not equal if ( cellVisibility != rangeFilterVisibility ) ( *cellVisibility ) = *rangeFilterVisibility; - const int elementCount = grid->elementCount(); + const int elementCount = part->elementCount(); if ( !propFilterColl->hasActiveFilters() ) return; @@ -124,10 +124,11 @@ void RivFemElmVisibilityCalculator::computePropertyVisibility( cvf::UByteArray* resVarAddress.resultPosType = RIG_ELEMENT_NODAL; const std::vector& resVals = - caseData->femPartResults()->resultValues( resVarAddress, grid->elementPartId(), timeStepIndex ); + caseData->femPartResults()->resultValues( resVarAddress, part->elementPartId(), timeStepIndex ); if ( !propertyFilter->isActive() ) continue; if ( !propertyFilter->resultDefinition->hasResult() ) continue; + if ( resVals.size() == 0 ) continue; const double lowerBound = propertyFilter->lowerBound(); const double upperBound = propertyFilter->upperBound(); @@ -145,7 +146,7 @@ void RivFemElmVisibilityCalculator::computePropertyVisibility( cvf::UByteArray* { if ( !( *cellVisibility )[cellIndex] ) continue; - size_t resultValueIndex = grid->elementNodeResultIdx( cellIndex, 0 ); + size_t resultValueIndex = part->elementNodeResultIdx( cellIndex, 0 ); double scalarValue = resVals[resultValueIndex]; int intValue = nearbyint( scalarValue ); if ( integerSet.find( intValue ) != integerSet.end() ) @@ -196,10 +197,10 @@ void RivFemElmVisibilityCalculator::computePropertyVisibility( cvf::UByteArray* { if ( !( *cellVisibility )[cellIndex] ) continue; - RigElementType eType = grid->elementType( cellIndex ); + RigElementType eType = part->elementType( cellIndex ); int elmNodeCount = RigFemTypes::elementNodeCount( eType ); - const int* elmNodeIndices = grid->connectivities( cellIndex ); + const int* elmNodeIndices = part->connectivities( cellIndex ); for ( int enIdx = 0; enIdx < elmNodeCount; ++enIdx ) { size_t resultValueIndex = cvf::UNDEFINED_SIZE_T; @@ -209,7 +210,7 @@ void RivFemElmVisibilityCalculator::computePropertyVisibility( cvf::UByteArray* } else { - resultValueIndex = grid->elementNodeResultIdx( cellIndex, enIdx ); + resultValueIndex = part->elementNodeResultIdx( cellIndex, enIdx ); } double scalarValue = resVals[resultValueIndex]; diff --git a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.cpp b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.cpp index 3f318f77c6..970b66ee9e 100644 --- a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.cpp @@ -42,8 +42,9 @@ using namespace cvf; //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RivFemPartGeometryGenerator::RivFemPartGeometryGenerator( const RigFemPart* part ) +RivFemPartGeometryGenerator::RivFemPartGeometryGenerator( const RigFemPart* part, cvf::Vec3d displayOffset ) : m_part( part ) + , m_displayOffset( displayOffset ) { CVF_ASSERT( part ); m_triangleMapper = new RivFemPartTriangleToElmMapper; @@ -147,7 +148,6 @@ void RivFemPartGeometryGenerator::computeArrays() trianglesToElements.reserve( estimatedQuadVxCount / 2 ); trianglesToElementFaces.reserve( estimatedQuadVxCount / 2 ); - cvf::Vec3d displayOffset = m_part->boundingBox().min(); const std::vector& nodeCoordinates = m_part->nodes().coordinates; #pragma omp parallel for schedule( dynamic ) @@ -177,13 +177,13 @@ void RivFemPartGeometryGenerator::computeArrays() if ( faceNodeCount == 4 ) { cvf::Vec3f quadVxs0( cvf::Vec3d( nodeCoordinates[elmNodeIndices[localElmNodeIndicesForFace[0]]] ) - - displayOffset ); + m_displayOffset ); cvf::Vec3f quadVxs1( cvf::Vec3d( nodeCoordinates[elmNodeIndices[localElmNodeIndicesForFace[1]]] ) - - displayOffset ); + m_displayOffset ); cvf::Vec3f quadVxs2( cvf::Vec3d( nodeCoordinates[elmNodeIndices[localElmNodeIndicesForFace[2]]] ) - - displayOffset ); + m_displayOffset ); cvf::Vec3f quadVxs3( cvf::Vec3d( nodeCoordinates[elmNodeIndices[localElmNodeIndicesForFace[3]]] ) - - displayOffset ); + m_displayOffset ); int qNodeIdx[4]; qNodeIdx[0] = elmNodeIndices[localElmNodeIndicesForFace[0]]; @@ -272,8 +272,6 @@ cvf::ref const int* elmNodeIndices = part->connectivities( elmIdx ); - // cvf::Vec3d displayOffset = part->boundingBox().min(); - for ( int lfIdx = 0; lfIdx < faceCount; ++lfIdx ) { int faceNodeCount = 0; diff --git a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.h b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.h index 053f71b66b..b98595f86b 100644 --- a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.h +++ b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.h @@ -64,7 +64,7 @@ private: class RivFemPartGeometryGenerator : public cvf::Object { public: - explicit RivFemPartGeometryGenerator( const RigFemPart* part ); + explicit RivFemPartGeometryGenerator( const RigFemPart* part, cvf::Vec3d displayOffset ); ~RivFemPartGeometryGenerator() override; // Setup methods @@ -102,6 +102,7 @@ private: // Input cvf::cref m_part; // The part being processed cvf::cref m_elmVisibility; + cvf::Vec3d m_displayOffset; // Created arrays cvf::ref m_quadVertices; diff --git a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp index 527df16ae6..0e182c8cf0 100644 --- a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp @@ -61,18 +61,25 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RivFemPartPartMgr::RivFemPartPartMgr( const RigFemPart* grid ) - : m_surfaceGenerator( grid ) - , m_grid( grid ) +RivFemPartPartMgr::RivFemPartPartMgr( const RigFemPart* part, cvf::Vec3d displayOffset ) + : m_surfaceGenerator( part, displayOffset ) + , m_part( part ) , m_opacityLevel( 1.0f ) , m_defaultColor( cvf::Color3::WHITE ) { - CVF_ASSERT( grid ); - m_gridIdx = grid->elementPartId(); + CVF_ASSERT( part ); + m_partIdx = part->elementPartId(); m_cellVisibility = new cvf::UByteArray; m_surfaceFacesTextureCoords = new cvf::Vec2fArray; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivFemPartPartMgr::~RivFemPartPartMgr() +{ +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -117,13 +124,13 @@ void RivFemPartPartMgr::generatePartGeometry( RivFemPartGeometryGenerator& geoBu } cvf::ref part = new cvf::Part; - part->setName( "FemPart " + cvf::String( m_gridIdx ) ); - part->setId( m_gridIdx ); // Use grid index as part ID + part->setName( "FemPart " + cvf::String( m_partIdx ) ); + part->setId( m_partIdx ); // Use part index as part ID part->setDrawable( geo.p() ); part->setTransform( m_scaleTransform.p() ); // Set mapping from triangle face index to element index - cvf::ref si = new RivFemPickSourceInfo( m_gridIdx, geoBuilder.triangleToElementMapper() ); + cvf::ref si = new RivFemPickSourceInfo( m_partIdx, geoBuilder.triangleToElementMapper() ); part->setSourceInfo( si.p() ); part->updateBoundingBox(); @@ -150,7 +157,7 @@ void RivFemPartPartMgr::generatePartGeometry( RivFemPartGeometryGenerator& geoBu } cvf::ref part = new cvf::Part; - part->setName( "Grid mesh " + cvf::String( m_gridIdx ) ); + part->setName( "Grid mesh " + cvf::String( m_partIdx ) ); part->setDrawable( geoMesh.p() ); part->setTransform( m_scaleTransform.p() ); @@ -181,8 +188,11 @@ void RivFemPartPartMgr::appendPartsToModel( cvf::ModelBasicList* model ) { CVF_ASSERT( model != nullptr ); - if ( m_surfaceFaces.notNull() ) model->addPart( m_surfaceFaces.p() ); - if ( m_surfaceGridLines.notNull() ) model->addPart( m_surfaceGridLines.p() ); + if ( m_part->enabled() ) + { + if ( m_surfaceFaces.notNull() ) model->addPart( m_surfaceFaces.p() ); + if ( m_surfaceGridLines.notNull() ) model->addPart( m_surfaceGridLines.p() ); + } } //-------------------------------------------------------------------------------------------------- @@ -199,6 +209,7 @@ const RivFemPartGeometryGenerator* RivFemPartPartMgr::surfaceGenerator() const void RivFemPartPartMgr::updateCellColor( cvf::Color4f color ) { if ( m_surfaceFaces.isNull() ) return; + if ( !m_part->enabled() ) return; // Set default effect caf::SurfaceEffectGenerator geometryEffgen( color, caf::PO_1 ); @@ -234,6 +245,8 @@ void RivFemPartPartMgr::updateCellResultColor( size_t timeStepIndex, RimGeoMechC { CVF_ASSERT( cellResultColors ); + if ( !m_part->enabled() ) return; + cvf::ref surfaceFacesColorArray; // Outer surface @@ -254,7 +267,7 @@ void RivFemPartPartMgr::updateCellResultColor( size_t timeStepIndex, RimGeoMechC } const std::vector& resultValues = - caseData->femPartResults()->resultValues( resVarAddress, m_gridIdx, (int)timeStepIndex ); + caseData->femPartResults()->resultValues( resVarAddress, m_partIdx, (int)timeStepIndex ); const std::vector* vxToResultMapping = nullptr; int vxCount = 0; @@ -329,10 +342,3 @@ void RivFemPartPartMgr::updateCellResultColor( size_t timeStepIndex, RimGeoMechC view->isLightingDisabled() ); } } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RivFemPartPartMgr::~RivFemPartPartMgr() -{ -} diff --git a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.h b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.h index 7cc8929114..e93ed39e4b 100644 --- a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.h +++ b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.h @@ -46,7 +46,7 @@ class RigFemPart; class RivFemPartPartMgr : public cvf::Object { public: - explicit RivFemPartPartMgr( const RigFemPart* femPart ); + explicit RivFemPartPartMgr( const RigFemPart* femPart, cvf::Vec3d displayOffset ); ~RivFemPartPartMgr() override; void setTransform( cvf::Transform* scaleTransform ); void setCellVisibility( cvf::UByteArray* cellVisibilities ); @@ -63,8 +63,8 @@ private: void generatePartGeometry( RivFemPartGeometryGenerator& geoBuilder ); private: - int m_gridIdx; - cvf::cref m_grid; + int m_partIdx; + cvf::cref m_part; cvf::ref m_scaleTransform; float m_opacityLevel; diff --git a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.cpp b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.cpp index fffa6a6f71..4f11ed075c 100644 --- a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.cpp @@ -50,9 +50,11 @@ void RivGeoMechPartMgr::clearAndSetReservoir( const RigGeoMechCaseData* geoMechC { const RigFemPartCollection* femParts = geoMechCase->femParts(); + cvf::Vec3d displayOffset = femParts->boundingBox().min(); + for ( int i = 0; i < femParts->partCount(); ++i ) { - m_femPartPartMgrs.push_back( new RivFemPartPartMgr( femParts->part( i ) ) ); + m_femPartPartMgrs.push_back( new RivFemPartPartMgr( femParts->part( i ), displayOffset ) ); } } } @@ -71,19 +73,19 @@ void RivGeoMechPartMgr::setTransform( cvf::Transform* scaleTransform ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivGeoMechPartMgr::setCellVisibility( size_t gridIndex, cvf::UByteArray* cellVisibilities ) +void RivGeoMechPartMgr::setCellVisibility( size_t partIndex, cvf::UByteArray* cellVisibilities ) { - CVF_ASSERT( gridIndex < m_femPartPartMgrs.size() ); - m_femPartPartMgrs[gridIndex]->setCellVisibility( cellVisibilities ); + CVF_ASSERT( partIndex < m_femPartPartMgrs.size() ); + m_femPartPartMgrs[partIndex]->setCellVisibility( cellVisibilities ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RivGeoMechPartMgr::cellVisibility( size_t gridIdx ) +cvf::ref RivGeoMechPartMgr::cellVisibility( size_t partIdx ) { - CVF_ASSERT( gridIdx < m_femPartPartMgrs.size() ); - return m_femPartPartMgrs[gridIdx]->cellVisibility(); + CVF_ASSERT( partIdx < m_femPartPartMgrs.size() ); + return m_femPartPartMgrs[partIdx]->cellVisibility(); } //-------------------------------------------------------------------------------------------------- @@ -122,13 +124,13 @@ void RivGeoMechPartMgr::appendGridPartsToModel( cvf::ModelBasicList* model ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivGeoMechPartMgr::appendGridPartsToModel( cvf::ModelBasicList* model, const std::vector& gridIndices ) +void RivGeoMechPartMgr::appendGridPartsToModel( cvf::ModelBasicList* model, const std::vector& partIndices ) { - for ( size_t i = 0; i < gridIndices.size(); ++i ) + for ( size_t i = 0; i < partIndices.size(); ++i ) { - if ( gridIndices[i] < m_femPartPartMgrs.size() ) + if ( partIndices[i] < m_femPartPartMgrs.size() ) { - m_femPartPartMgrs[gridIndices[i]]->appendPartsToModel( model ); + m_femPartPartMgrs[partIndices[i]]->appendPartsToModel( model ); } } } diff --git a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp index 6ae7a42f95..6e3f4254f8 100644 --- a/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp +++ b/ApplicationLibCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp @@ -202,10 +202,11 @@ RivGeoMechPartMgr* RivGeoMechVizLogic::getUpdatedPartMgr( RivGeoMechPartMgrCache partMgrToUpdate->clearAndSetReservoir( caseData ); } + partMgrToUpdate->setTransform( m_geomechView->scaleTransform() ); + for ( int femPartIdx = 0; femPartIdx < partCount; ++femPartIdx ) { cvf::ref elmVisibility = partMgrToUpdate->cellVisibility( femPartIdx ); - partMgrToUpdate->setTransform( m_geomechView->scaleTransform() ); if ( pMgrKey.geometryType() == RANGE_FILTERED ) { @@ -269,9 +270,12 @@ void RivGeoMechVizLogic::calculateCurrentTotalCellVisibility( cvf::UByteArray* t if ( gridCount == 0 ) return; - RigFemPart* part = m_geomechView->femParts()->part( 0 ); - int elmCount = part->elementCount(); - + int elmCount = 0; + for ( int i = 0; i < m_geomechView->femParts()->partCount(); i++ ) + { + RigFemPart* part = m_geomechView->femParts()->part( i ); + elmCount += part->elementCount(); + } totalVisibility->resize( elmCount ); totalVisibility->setAll( false ); @@ -282,10 +286,17 @@ void RivGeoMechVizLogic::calculateCurrentTotalCellVisibility( cvf::UByteArray* t CVF_ASSERT( partMgr ); if ( partMgr ) { - cvf::ref visibility = partMgr->cellVisibility( 0 ); - for ( int elmIdx = 0; elmIdx < elmCount; ++elmIdx ) + int elmOffset = 0; + for ( int i = 0; i < m_geomechView->femParts()->partCount(); i++ ) { - ( *totalVisibility )[elmIdx] |= ( *visibility )[elmIdx]; + RigFemPart* part = m_geomechView->femParts()->part( i ); + + cvf::ref visibility = partMgr->cellVisibility( i ); + for ( int elmIdx = 0; elmIdx < part->elementCount(); ++elmIdx ) + { + ( *totalVisibility )[elmOffset + elmIdx] |= ( *visibility )[elmIdx]; + } + elmOffset += part->elementCount(); } } } diff --git a/ApplicationLibCode/GeoMech/OdbReader/RifOdbReader.cpp b/ApplicationLibCode/GeoMech/OdbReader/RifOdbReader.cpp index 415d032baa..942ff62bce 100644 --- a/ApplicationLibCode/GeoMech/OdbReader/RifOdbReader.cpp +++ b/ApplicationLibCode/GeoMech/OdbReader/RifOdbReader.cpp @@ -35,6 +35,7 @@ #include "RigFemPart.h" #include "RigFemPartCollection.h" +#include "RigFemTypes.h" #include "cafProgressInfo.h" #include @@ -97,14 +98,16 @@ size_t RifOdbReader::sm_instanceCount = 0; //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - std::map initFemTypeMap() { std::map typeMap; - typeMap["C3D8R"] = HEX8; - typeMap["C3D8"] = HEX8; - typeMap["C3D8P"] = HEX8P; - typeMap["CAX4"] = CAX4; + typeMap["C3D8R"] = HEX8; + typeMap["C3D8"] = HEX8; + typeMap["C3D8P"] = HEX8P; + typeMap["CAX4"] = CAX4; + typeMap["C3D20RT"] = HEX8; + typeMap["C3D8RT"] = HEX8; + typeMap["C3D8R"] = HEX8; return typeMap; } @@ -129,30 +132,6 @@ RigElementType toRigElementType( const odb_String& odbTypeName ) return it->second; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- - -const int* localElmNodeToIntegrationPointMapping( RigElementType elmType ) -{ - static const int HEX8_Mapping[8] = { 0, 1, 3, 2, 4, 5, 7, 6 }; - - switch ( elmType ) - { - case HEX8: - case HEX8P: - return HEX8_Mapping; - break; - case CAX4: - return HEX8_Mapping; // First four is identical to HEX8 - break; - default: - // assert(false); // Element type not supported - break; - } - return NULL; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -335,7 +314,7 @@ bool RifOdbReader::readFemParts( RigFemPartCollection* femParts ) odb_InstanceRepository instanceRepository = m_odb->rootAssembly().instances(); odb_InstanceRepositoryIT iter( instanceRepository ); - caf::ProgressInfo modelProgress( instanceRepository.size() * ( 2 + 4 ), "Reading Odb Parts" ); + caf::ProgressInfo modelProgress( instanceRepository.size() * ( size_t )( 2 + 4 ), "Reading Odb Parts" ); int instanceCount = 0; for ( iter.first(); !iter.isDone(); iter.next(), instanceCount++ ) @@ -343,10 +322,14 @@ bool RifOdbReader::readFemParts( RigFemPartCollection* femParts ) modelProgress.setProgressDescription( QString( iter.currentKey().cStr() ) + ": Reading Nodes" ); m_nodeIdToIdxMaps.push_back( std::map() ); - odb_Instance& inst = instanceRepository[iter.currentKey()]; + const auto& key = iter.currentKey(); + + odb_Instance& inst = instanceRepository[key]; RigFemPart* femPart = new RigFemPart; + femPart->setName( key.cStr() ); + // Extract nodes const odb_SequenceNode& odbNodes = inst.nodes(); @@ -372,7 +355,7 @@ bool RifOdbReader::readFemParts( RigFemPartCollection* femParts ) } modelProgress.incrementProgress(); - modelProgress.setProgressDescription( QString( iter.currentKey().cStr() ) + ": Reading Elements" ); + modelProgress.setProgressDescription( QString( key.cStr() ) + ": Reading Elements" ); // Extract elements const odb_SequenceElement& elements = inst.elements(); @@ -396,6 +379,8 @@ bool RifOdbReader::readFemParts( RigFemPartCollection* femParts ) int nodeCount = 0; const int* idBasedConnectivities = odbElm.connectivity( nodeCount ); + nodeCount = std::min( nodeCount, RigFemTypes::elementNodeCount( elmType ) ); + CVF_TIGHT_ASSERT( nodeCount == RigFemTypes::elementNodeCount( elmType ) ); indexBasedConnectivities.resize( nodeCount ); @@ -633,13 +618,28 @@ odb_Instance* RifOdbReader::instance( int instanceIndex ) //-------------------------------------------------------------------------------------------------- /// Get the number of result items (== #nodes or #elements) //-------------------------------------------------------------------------------------------------- -size_t RifOdbReader::resultItemCount( const std::string& fieldName, int partIndex, int stepIndex, int frameIndex ) +size_t RifOdbReader::resultItemCount( const std::string& fieldName, + int partIndex, + int stepIndex, + int frameIndex, + ResultPosition resultPosition ) { odb_Instance* partInstance = instance( partIndex ); CVF_ASSERT( partInstance != NULL ); - const odb_Frame& frame = stepFrame( stepIndex, frameIndex ); - const odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset( *partInstance ); + const odb_Frame& frame = stepFrame( stepIndex, frameIndex ); + odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset( *partInstance ); + + if ( resultPosition != NONE ) + { + odb_Enum::odb_ResultPositionEnum odbResultPos = odb_Enum::NODAL; + if ( resultPosition == ELEMENT_NODAL ) + odbResultPos = odb_Enum::ELEMENT_NODAL; + else if ( resultPosition == INTEGRATION_POINT ) + odbResultPos = odb_Enum::INTEGRATION_POINT; + instanceFieldOutput = instanceFieldOutput.getSubset( odbResultPos ); + } + const odb_SequenceFieldBulkData& seqFieldBulkData = instanceFieldOutput.bulkDataBlocks(); size_t resultItemCount = 0; @@ -647,8 +647,34 @@ size_t RifOdbReader::resultItemCount( const std::string& fieldName, int partInde for ( int block = 0; block < numBlocks; block++ ) { - const odb_FieldBulkData& bulkData = seqFieldBulkData[block]; - resultItemCount += bulkData.length(); + const odb_FieldBulkData& bulkData = seqFieldBulkData[block]; + int numValues = bulkData.length(); + + if ( resultPosition == INTEGRATION_POINT ) + { + int numValues = bulkData.length(); + int elemCount = bulkData.numberOfElements(); + int ipCount = numValues / elemCount; + + // handle reduced integration point elements by using the same value 8 times + if ( ipCount == 1 ) + resultItemCount += numValues * 8; + else + resultItemCount += numValues; + } + else if ( resultPosition == ELEMENT_NODAL ) + { + int numValues = bulkData.length(); + int elemCount = bulkData.numberOfElements(); + int elemNodeCount = numValues / elemCount; + + // handle that we use just 8 nodes per element + resultItemCount += elemCount * std::min( elemNodeCount, 8 ); + } + else + { + resultItemCount += numValues; + } } return resultItemCount; @@ -713,7 +739,7 @@ void RifOdbReader::readDisplacements( int partIndex, int stepIndex, int frameInd odb_Instance* partInstance = instance( partIndex ); CVF_ASSERT( partInstance != NULL ); - size_t dataSize = resultItemCount( "U", partIndex, stepIndex, frameIndex ); + size_t dataSize = resultItemCount( "U", partIndex, stepIndex, frameIndex, NONE ); if ( dataSize > 0 ) { displacements->resize( dataSize ); @@ -821,7 +847,7 @@ void RifOdbReader::readElementNodeField( const std::string& field size_t compCount = componentsCount( fieldName, ELEMENT_NODAL ); CVF_ASSERT( compCount == resultValues->size() ); - size_t dataSize = resultItemCount( fieldName, partIndex, stepIndex, frameIndex ); + size_t dataSize = resultItemCount( fieldName, partIndex, stepIndex, frameIndex, ELEMENT_NODAL ); if ( dataSize > 0 ) { for ( int comp = 0; comp < compCount; comp++ ) @@ -853,13 +879,16 @@ void RifOdbReader::readElementNodeField( const std::string& field int* elementLabels = bulkData.elementLabels(); float* data = bulkDataGetter.data(); + // use max HEX8 nodes + int usedElemNodeCount = std::min( elemNodeCount, 8 ); + for ( int elem = 0; elem < elemCount; elem++ ) { int elementIdx = elementIdToIdxMap[elementLabels[elem * elemNodeCount]]; - int elementResultStartDestIdx = elementIdx * elemNodeCount; // Ikke generellt riktig ! + int elementResultStartDestIdx = elementIdx * usedElemNodeCount; int elementResultStartSourceIdx = elem * elemNodeCount * numComp; - for ( int elemNode = 0; elemNode < elemNodeCount; elemNode++ ) + for ( int elemNode = 0; elemNode < usedElemNodeCount; elemNode++ ) { int destIdx = elementResultStartDestIdx + elemNode; int srcIdx = elementResultStartSourceIdx + elemNode * numComp; @@ -890,7 +919,7 @@ void RifOdbReader::readIntegrationPointField( const std::string& size_t compCount = componentsCount( fieldName, INTEGRATION_POINT ); CVF_ASSERT( compCount == resultValues->size() ); - size_t dataSize = resultItemCount( fieldName, partIndex, stepIndex, frameIndex ); + size_t dataSize = resultItemCount( fieldName, partIndex, stepIndex, frameIndex, INTEGRATION_POINT ); if ( dataSize > 0 ) { for ( int comp = 0; comp < compCount; comp++ ) @@ -919,27 +948,26 @@ void RifOdbReader::readIntegrationPointField( const std::string& int numComp = bulkData.width(); int elemCount = bulkData.numberOfElements(); int ipCount = numValues / elemCount; + int ipDestCount = std::max( ipCount, 8 ); // always use max. 8 integration points in destination int* elementLabels = bulkData.elementLabels(); float* data = bulkDataGetter.data(); - RigElementType eType = toRigElementType( bulkData.baseElementType() ); - const int* elmNodeToIpResultMapping = - localElmNodeToIntegrationPointMapping( eType ); // Todo: Use the one in RigFemTypes.h, but we need to guard - // against unknown element types first. - if ( !elmNodeToIpResultMapping ) continue; + RigElementType eType = toRigElementType( bulkData.baseElementType() ); + const int* elmNodeToIpResultMapping = RigFemTypes::localElmNodeToIntegrationPointMapping( eType ); for ( int elem = 0; elem < elemCount; elem++ ) { int elementIdx = elementIdToIdxMap[elementLabels[elem * ipCount]]; - int elementResultStartDestIdx = elementIdx * ipCount; // Ikke generellt riktig ! + int elementResultStartDestIdx = elementIdx * ipDestCount; int elementResultStartSourceIdx = elem * ipCount * numComp; - for ( int ipIdx = 0; ipIdx < ipCount; ipIdx++ ) + for ( int ipIdx = 0; ipIdx < ipDestCount; ipIdx++ ) { - int resultIpIdx = elmNodeToIpResultMapping[ipIdx]; - int destIdx = elementResultStartDestIdx + ipIdx; + int resultIpIdx = elmNodeToIpResultMapping[std::min( ipIdx, ipCount - 1 )]; int srcIdx = elementResultStartSourceIdx + resultIpIdx * numComp; + int destIdx = elementResultStartDestIdx + ipIdx; + for ( int comp = 0; comp < numComp; comp++ ) { ( *( *resultValues )[comp] )[destIdx] = data[srcIdx + comp]; diff --git a/ApplicationLibCode/GeoMech/OdbReader/RifOdbReader.h b/ApplicationLibCode/GeoMech/OdbReader/RifOdbReader.h index 5c9e6dbbb9..c32b894fc5 100644 --- a/ApplicationLibCode/GeoMech/OdbReader/RifOdbReader.h +++ b/ApplicationLibCode/GeoMech/OdbReader/RifOdbReader.h @@ -78,7 +78,8 @@ private: { NODAL, ELEMENT_NODAL, - INTEGRATION_POINT + INTEGRATION_POINT, + NONE }; class RifOdbResultKey @@ -104,7 +105,11 @@ private: void assertMetaDataLoaded(); void close(); - size_t resultItemCount( const std::string& fieldName, int partIndex, int stepIndex, int frameIndex ); + size_t resultItemCount( const std::string& fieldName, + int partIndex, + int stepIndex, + int frameIndex, + ResultPosition resultPosition ); size_t componentsCount( const std::string& fieldName, ResultPosition position ); const odb_Frame& stepFrame( int stepIndex, int frameIndex ) const; odb_Instance* instance( int instanceIndex ); diff --git a/ApplicationLibCode/ModelVisualization/RivTensorResultPartMgr.cpp b/ApplicationLibCode/ModelVisualization/RivTensorResultPartMgr.cpp index 730370f30a..9b83679601 100644 --- a/ApplicationLibCode/ModelVisualization/RivTensorResultPartMgr.cpp +++ b/ApplicationLibCode/ModelVisualization/RivTensorResultPartMgr.cpp @@ -94,8 +94,10 @@ void RivTensorResultPartMgr::appendDynamicGeometryPartsToModel( cvf::ModelBasicL for ( int partIdx = 0; partIdx < femParts->partCount(); partIdx++ ) { std::vector vertexTensors = resultCollection->tensors( address, partIdx, (int)frameIndex ); + if ( vertexTensors.empty() ) continue; + + const RigFemPart* part = femParts->part( partIdx ); - const RigFemPart* part = femParts->part( partIdx ); std::vector elmTensors; calculateElementTensors( *part, vertexTensors, &elmTensors ); @@ -129,7 +131,8 @@ void RivTensorResultPartMgr::appendDynamicGeometryPartsToModel( cvf::ModelBasicL for ( const RivGeoMechPartMgrCache::Key& partKey : partKeys ) { const RivGeoMechPartMgr* partMgr = partMgrCache->partMgr( partKey ); - for ( auto mgr : partMgr->femPartMgrs() ) + + auto mgr = partMgr->femPartMgrs()[partIdx]; { const RivFemPartGeometryGenerator* surfaceGenerator = mgr->surfaceGenerator(); const std::vector& quadVerticesToNodeIdxMapping = surfaceGenerator->quadVerticesToNodeIdxMapping(); diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/CMakeLists_files.cmake b/ApplicationLibCode/ProjectDataModel/GeoMech/CMakeLists_files.cmake index d601f5a1c8..c634b8a2b3 100644 --- a/ApplicationLibCode/ProjectDataModel/GeoMech/CMakeLists_files.cmake +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/CMakeLists_files.cmake @@ -7,6 +7,8 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RimGeoMechContourMapProjection.h ${CMAKE_CURRENT_LIST_DIR}/RimGeoMechContourMapView.h ${CMAKE_CURRENT_LIST_DIR}/RimGeoMechContourMapViewCollection.h + ${CMAKE_CURRENT_LIST_DIR}/RimGeoMechPartCollection.h + ${CMAKE_CURRENT_LIST_DIR}/RimGeoMechPart.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -18,6 +20,8 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RimGeoMechContourMapProjection.cpp ${CMAKE_CURRENT_LIST_DIR}/RimGeoMechContourMapView.cpp ${CMAKE_CURRENT_LIST_DIR}/RimGeoMechContourMapViewCollection.cpp + ${CMAKE_CURRENT_LIST_DIR}/RimGeoMechPartCollection.cpp + ${CMAKE_CURRENT_LIST_DIR}/RimGeoMechPart.cpp ) list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES}) diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPart.cpp b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPart.cpp new file mode 100644 index 0000000000..d0fc8aa073 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPart.cpp @@ -0,0 +1,81 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021- 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 "RimGeoMechPart.h" + +#include "RimGeoMechView.h" + +#include "cafPdmFieldScriptingCapability.h" +#include "cafPdmObjectScriptingCapability.h" + +CAF_PDM_SOURCE_INIT( RimGeoMechPart, "GeoMechPart" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGeoMechPart::RimGeoMechPart() +{ + CAF_PDM_InitScriptableObject( "GeoMechPart", ":/GeoMechCase24x24.png", "", "" ); + + CAF_PDM_InitScriptableFieldNoDefault( &m_partId, "PartId", "Part Id", "", "", "" ); + m_partId.uiCapability()->setUiReadOnly( true ); + + nameField()->uiCapability()->setUiReadOnly( true ); + + setDeletable( false ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGeoMechPart::~RimGeoMechPart() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechPart::setPartId( int partId ) +{ + m_partId = partId; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimGeoMechPart::partId() const +{ + return m_partId; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechPart::fieldChangedByUi( const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue ) +{ + updateUiIconFromToggleField(); + + if ( changedField == objectToggleField() ) + { + RimGeoMechView* ownerView; + firstAncestorOrThisOfType( ownerView ); + if ( ownerView ) ownerView->scheduleCreateDisplayModelAndRedraw(); + } +} diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPart.h b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPart.h new file mode 100644 index 0000000000..4e8ff0df81 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPart.h @@ -0,0 +1,42 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021- 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 "RimCheckableNamedObject.h" + +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +class RimGeoMechPart : public RimCheckableNamedObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimGeoMechPart(); + ~RimGeoMechPart() override; + + void setPartId( int partId ); + int partId() const; + +protected: + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; + +private: + caf::PdmField m_partId; +}; diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPartCollection.cpp b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPartCollection.cpp new file mode 100644 index 0000000000..6034f34153 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPartCollection.cpp @@ -0,0 +1,112 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021- 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 "RimGeoMechPartCollection.h" + +#include "RigFemPartCollection.h" +#include "RigGeoMechCaseData.h" + +#include "RimGeoMechCase.h" +#include "RimGeoMechPart.h" + +#include "RiaLogging.h" + +#include "cafPdmFieldScriptingCapability.h" +#include "cafPdmObjectScriptingCapability.h" + +CAF_PDM_SOURCE_INIT( RimGeoMechPartCollection, "GeoMechPartCollection" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGeoMechPartCollection::RimGeoMechPartCollection() + : m_case( nullptr ) +{ + CAF_PDM_InitScriptableObject( "Parts", ":/GeoMechCase24x24.png", "", "" ); + + CAF_PDM_InitScriptableFieldNoDefault( &m_parts, "Parts", "Parts", "", "", "" ); + m_parts.uiCapability()->setUiTreeHidden( true ); + + setDeletable( false ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGeoMechPartCollection::~RimGeoMechPartCollection() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechPartCollection::syncWithCase( RimGeoMechCase* geoCase ) +{ + m_case = geoCase; + + if ( geoCase && geoCase->geoMechData() && geoCase->geoMechData()->femParts() ) + { + const int count = geoCase->geoMechData()->femParts()->partCount(); + + if ( count != (int)m_parts.size() ) + { + m_parts.clear(); + + for ( int i = 0; i < count; i++ ) + { + const auto& femPart = geoCase->geoMechData()->femParts()->part( i ); + + RimGeoMechPart* part = new RimGeoMechPart(); + part->setPartId( i ); + part->setName( QString( femPart->name().c_str() ) ); + part->setCheckState( femPart->enabled() ); + m_parts.push_back( part ); + } + } + } + updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimGeoMechPartCollection::parts() const +{ + return m_parts.childObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimGeoMechPartCollection::shouldBeVisibleInTree() const +{ + return m_parts.size() > 1; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimGeoMechPartCollection::isPartEnabled( int partId ) const +{ + for ( const auto& part : m_parts ) + { + if ( part->partId() == partId ) return part->isChecked(); + } + + return false; +} diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPartCollection.h b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPartCollection.h new file mode 100644 index 0000000000..78636d0ca2 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechPartCollection.h @@ -0,0 +1,46 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021- 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" + +class RimGeoMechPart; +class RimGeoMechCase; + +class RimGeoMechPartCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimGeoMechPartCollection(); + ~RimGeoMechPartCollection() override; + + void syncWithCase( RimGeoMechCase* geoCase ); + + bool shouldBeVisibleInTree() const; + + bool isPartEnabled( int partId ) const; + + std::vector parts() const; + +private: + caf::PdmChildArrayField m_parts; + RimGeoMechCase* m_case; +}; diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.cpp b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.cpp index 371e900d98..bd0fea3546 100644 --- a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.cpp +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.cpp @@ -37,6 +37,8 @@ #include "RimEclipseView.h" #include "RimGeoMechCase.h" #include "RimGeoMechCellColors.h" +#include "RimGeoMechPart.h" +#include "RimGeoMechPartCollection.h" #include "RimGeoMechPropertyFilterCollection.h" #include "RimGridCollection.h" #include "RimIntersectionCollection.h" @@ -96,6 +98,10 @@ RimGeoMechView::RimGeoMechView( void ) m_propertyFilterCollection = new RimGeoMechPropertyFilterCollection(); m_propertyFilterCollection.uiCapability()->setUiHidden( true ); + CAF_PDM_InitFieldNoDefault( &m_partsCollection, "Parts", "Parts", "", "", "" ); + m_partsCollection = new RimGeoMechPartCollection(); + m_partsCollection.uiCapability()->setUiHidden( true ); + m_scaleTransform = new cvf::Transform(); m_vizLogic = new RivGeoMechVizLogic( this ); m_tensorPartMgr = new RivTensorResultPartMgr( this ); @@ -175,7 +181,9 @@ void RimGeoMechView::onLoadDataAndUpdate() this->geoMechPropertyFilterCollection()->loadAndInitializePropertyFilters(); m_wellMeasurementCollection->syncWithChangesInWellMeasurementCollection(); - if ( this->m_surfaceCollection ) this->m_surfaceCollection->loadData(); + if ( m_surfaceCollection ) m_surfaceCollection->loadData(); + + if ( m_partsCollection ) m_partsCollection->syncWithCase( m_geomechCase ); this->scheduleCreateDisplayModelAndRedraw(); @@ -184,8 +192,6 @@ void RimGeoMechView::onLoadDataAndUpdate() //-------------------------------------------------------------------------------------------------- /// -/// Todo: Work in progress -/// //-------------------------------------------------------------------------------------------------- void RimGeoMechView::onUpdateScaleTransform() @@ -244,10 +250,16 @@ void RimGeoMechView::onCreateDisplayModel() if ( !( m_geomechCase && m_geomechCase->geoMechData() && m_geomechCase->geoMechData()->femParts() ) ) return; - int partCount = m_geomechCase->geoMechData()->femParts()->partCount(); + const auto& theParts = femParts(); + int partCount = theParts->partCount(); if ( partCount <= 0 ) return; + for ( int i = 0; i < partCount; i++ ) + { + theParts->part( i )->setEnabled( m_partsCollection()->isPartEnabled( i ) ); + } + // Remove all existing animation frames from the viewer. // The parts are still cached in the RivReservoir geometry and friends @@ -956,6 +968,7 @@ void RimGeoMechView::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrderin { uiTreeOrdering.add( m_overlayInfoConfig() ); uiTreeOrdering.add( m_gridCollection() ); + if ( m_partsCollection->shouldBeVisibleInTree() ) uiTreeOrdering.add( m_partsCollection() ); uiTreeOrdering.add( cellResult() ); uiTreeOrdering.add( m_tensorResults() ); @@ -986,3 +999,11 @@ const RimPropertyFilterCollection* RimGeoMechView::propertyFilterCollection() co { return geoMechPropertyFilterCollection(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RimGeoMechPartCollection* RimGeoMechView::partsCollection() const +{ + return m_partsCollection(); +} diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.h b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.h index 070ea116e6..6a2cb0e750 100644 --- a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.h +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.h @@ -45,6 +45,7 @@ class RiuViewer; class RivGeoMechPartMgr; class RivGeoMechVizLogic; class RivTensorResultPartMgr; +class RimGeoMechPartCollection; namespace cvf { @@ -73,6 +74,8 @@ public: const RimPropertyFilterCollection* propertyFilterCollection() const override; + const RimGeoMechPartCollection* partsCollection() const; + RimGeoMechPropertyFilterCollection* geoMechPropertyFilterCollection(); const RimGeoMechPropertyFilterCollection* geoMechPropertyFilterCollection() const; void setOverridePropertyFilterCollection( RimGeoMechPropertyFilterCollection* pfc ); @@ -133,6 +136,7 @@ private: caf::PdmChildField m_tensorResults; caf::PdmChildField m_propertyFilterCollection; caf::PdmPointer m_overridePropertyFilterCollection; + caf::PdmChildField m_partsCollection; caf::PdmPointer m_geomechCase; cvf::ref m_vizLogic;