Support filtering on element sets (#10570)

* Add support for filtering on element sets in geomech cases
This commit is contained in:
jonjenssen 2023-09-04 15:48:08 +02:00 committed by GitHub
parent f4255ba16e
commit e5fa4ae8c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 597 additions and 72 deletions

View File

@ -8,6 +8,7 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RicNewRangeFilterSliceKFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicNewRangeFilterSlice3dviewFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicNewPolygonFilter3dviewFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicNewCellIndexFilterFeature.h
)
set(SOURCE_GROUP_SOURCE_FILES
@ -20,6 +21,7 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RicNewRangeFilterSliceKFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicNewRangeFilterSlice3dviewFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicNewPolygonFilter3dviewFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicNewCellIndexFilterFeature.cpp
)
list(APPEND COMMAND_CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})

View File

@ -0,0 +1,78 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RicNewCellIndexFilterFeature.h"
#include "RiaApplication.h"
#include "RimCase.h"
#include "RimCellFilterCollection.h"
#include "RimCellIndexFilter.h"
#include "RimGeoMechCase.h"
#include "RimGridView.h"
#include "RimUserDefinedFilter.h"
#include "Riu3DMainWindowTools.h"
#include "cafSelectionManagerTools.h"
#include "cafUtils.h"
#include <QAction>
CAF_CMD_SOURCE_INIT( RicNewCellIndexFilterFeature, "RicNewCellIndexFilterFeature" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicNewCellIndexFilterFeature::isCommandEnabled() const
{
RimGridView* view = RiaApplication::instance()->activeGridView();
if ( !view ) return false;
RimGeoMechCase* gCase = dynamic_cast<RimGeoMechCase*>( view->ownerCase() );
return gCase != nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicNewCellIndexFilterFeature::onActionTriggered( bool isChecked )
{
// Find the selected Cell Filter Collection
std::vector<RimCellFilterCollection*> colls = caf::selectedObjectsByTypeStrict<RimCellFilterCollection*>();
if ( colls.empty() ) return;
RimCellFilterCollection* filtColl = colls[0];
// and the case to use
RimCase* sourceCase = filtColl->firstAncestorOrThisOfTypeAsserted<RimCase>();
RimCellIndexFilter* lastCreatedOrUpdated = filtColl->addNewCellIndexFilter( sourceCase );
if ( lastCreatedOrUpdated )
{
Riu3DMainWindowTools::selectAsCurrentItem( lastCreatedOrUpdated );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicNewCellIndexFilterFeature::setupActionLook( QAction* actionToSetup )
{
actionToSetup->setIcon( QIcon( ":/CellFilter_UserDefined.png" ) );
actionToSetup->setText( "New Element Set Filter" );
}

View File

@ -0,0 +1,34 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafCmdFeature.h"
//==================================================================================================
///
//==================================================================================================
class RicNewCellIndexFilterFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
protected:
bool isCommandEnabled() const override;
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
};

View File

@ -146,7 +146,7 @@ bool RigFemPart::fillElementCoordinates( size_t elementIdx, std::array<cvf::Vec3
// Fill coordinates for each node
const auto& partNodes = nodes();
for ( int i = 0; i < nodeIndices.size(); ++i )
for ( int i = 0; i < (int)nodeIndices.size(); ++i )
{
coordinates[i].set( partNodes.coordinates[nodeIndices[i]] );
}
@ -638,3 +638,45 @@ bool RigFemPart::enabled() const
{
return m_enabled;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFemPart::addElementSet( std::string name, const std::vector<size_t>& elementIds )
{
m_elementSetNames.push_back( name );
std::map<size_t, size_t> idToIndex;
for ( size_t i = 0; i < m_elementId.size(); i++ )
{
idToIndex[m_elementId[i]] = i;
}
std::vector<size_t> elementIndexes;
elementIndexes.resize( elementIds.size() );
for ( size_t i = 0; i < elementIds.size(); i++ )
{
elementIndexes[i] = idToIndex[elementIds[i] + 1];
}
m_elementIndexSets.push_back( elementIndexes );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::string> RigFemPart::elementSetNames() const
{
return m_elementSetNames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<size_t> RigFemPart::elementSet( int setIndex ) const
{
if ( ( setIndex < 0 ) || ( setIndex >= (int)m_elementIndexSets.size() ) ) return {};
return m_elementIndexSets[setIndex];
}

View File

@ -102,6 +102,10 @@ public:
void setEnabled( bool enable );
bool enabled() const;
void addElementSet( std::string name, const std::vector<size_t>& elementIds );
std::vector<std::string> elementSetNames() const;
std::vector<size_t> elementSet( int setIndex ) const;
private:
int m_elementPartId;
std::string m_name;
@ -112,6 +116,9 @@ private:
std::vector<size_t> m_elementConnectivityStartIndices;
std::vector<int> m_allElementConnectivities;
std::vector<std::string> m_elementSetNames;
std::vector<std::vector<size_t>> m_elementIndexSets;
RigFemPartNodes m_nodes;
mutable cvf::ref<RigFemPartGrid> m_structGrid;

View File

@ -47,8 +47,8 @@ public:
virtual std::vector<double> frameTimes( int stepIndex ) const = 0;
virtual int frameCount( int stepIndex ) const = 0;
virtual std::vector<std::string> elementSetNames( int partIndex ) = 0;
virtual std::vector<size_t> elementSet( int partIndex, int setIndex ) = 0;
virtual std::vector<std::string> elementSetNames( int partIndex, std::string partName ) = 0;
virtual std::vector<size_t> elementSet( int partIndex, std::string partName, int setIndex ) = 0;
virtual std::map<std::string, std::vector<std::string>> scalarNodeFieldAndComponentNames() = 0;
virtual std::map<std::string, std::vector<std::string>> scalarElementNodeFieldAndComponentNames() = 0;

View File

@ -322,8 +322,8 @@ bool RifOdbReader::readFemParts( RigFemPartCollection* femParts )
caf::ProgressInfo modelProgress( instanceRepository.size() * (size_t)( 2 + 4 ), "Reading Odb Parts" );
int instanceCount = 0;
for ( iter.first(); !iter.isDone(); iter.next(), instanceCount++ )
int partIdx = 0;
for ( iter.first(); !iter.isDone(); iter.next(), partIdx++ )
{
modelProgress.setProgressDescription( QString( iter.currentKey().cStr() ) + ": Reading Nodes" );
m_nodeIdToIdxMaps.push_back( std::map<int, int>() );
@ -404,7 +404,14 @@ bool RifOdbReader::readFemParts( RigFemPartCollection* femParts )
}
}
femPart->setElementPartId( femParts->partCount() );
// read element sets
auto setNames = elementSetNames( partIdx, femPart->name() );
for ( int setIndex = 0; setIndex < (int)setNames.size(); setIndex++ )
{
femPart->addElementSet( setNames[setIndex], elementSet( partIdx, femPart->name(), setIndex ) );
}
femPart->setElementPartId( partIdx );
femParts->addFemPart( femPart );
modelProgress.incrementProgress();
@ -507,7 +514,7 @@ int RifOdbReader::frameCount( int stepIndex ) const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::string> RifOdbReader::elementSetNames( int partIndex )
std::vector<std::string> RifOdbReader::elementSetNames( int partIndex, std::string partInstanceName )
{
CVF_ASSERT( m_odb != NULL );
@ -533,7 +540,16 @@ std::vector<std::string> RifOdbReader::elementSetNames( int partIndex )
for ( setIt.first(); !setIt.isDone(); setIt.next() )
{
const odb_Set& set = setIt.currentValue();
setNames.push_back( set.name().CStr() );
auto names = set.instanceNames();
for ( int i = 0; i < names.size(); i++ )
{
if ( names[i].CStr() == partInstanceName )
{
setNames.push_back( set.name().CStr() );
break;
}
}
}
break;
@ -549,17 +565,14 @@ std::vector<std::string> RifOdbReader::elementSetNames( int partIndex )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<size_t> RifOdbReader::elementSet( int partIndex, int setIndex )
std::vector<size_t> RifOdbReader::elementSet( int partIndex, std::string partName, int setIndex )
{
CVF_ASSERT( m_odb != NULL );
std::vector<std::string> setNames = elementSetNames( partIndex );
const odb_Assembly& rootAssembly = m_odb->constRootAssembly();
const odb_Assembly& rootAssembly = m_odb->constRootAssembly();
const odb_Set& set = rootAssembly.elementSets()[odb_String( m_partElementSetNames[partIndex][setIndex].c_str() )];
const odb_Set& set = rootAssembly.elementSets()[odb_String( setNames[setIndex].c_str() )];
odb_SequenceString instanceNames = set.instanceNames();
const odb_SequenceElement& setElements = set.elements( instanceNames[partIndex] );
const odb_SequenceElement& setElements = set.elements( partName.c_str() );
int elementCount = setElements.size();
std::vector<size_t> elementIndexes;

View File

@ -49,8 +49,8 @@ public:
std::vector<double> frameTimes( int stepIndex ) const override;
int frameCount( int stepIndex ) const override;
std::vector<std::string> elementSetNames( int partIndex ) override;
std::vector<size_t> elementSet( int partIndex, int setIndex ) override;
std::vector<std::string> elementSetNames( int partIndex, std::string partName ) override;
std::vector<size_t> elementSet( int partIndex, std::string partName, int setIndex ) override;
std::map<std::string, std::vector<std::string>> scalarNodeFieldAndComponentNames() override;
std::map<std::string, std::vector<std::string>> scalarElementNodeFieldAndComponentNames() override;

View File

@ -11,6 +11,7 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RimPolygonFilter.h
${CMAKE_CURRENT_LIST_DIR}/RimUserDefinedFilter.h
${CMAKE_CURRENT_LIST_DIR}/RimCellFilterIntervalTool.h
${CMAKE_CURRENT_LIST_DIR}/RimCellIndexFilter.h
)
set(SOURCE_GROUP_SOURCE_FILES
@ -26,6 +27,7 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RimPolygonFilter.cpp
${CMAKE_CURRENT_LIST_DIR}/RimUserDefinedFilter.cpp
${CMAKE_CURRENT_LIST_DIR}/RimCellFilterIntervalTool.cpp
${CMAKE_CURRENT_LIST_DIR}/RimCellIndexFilter.cpp
)
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})

View File

@ -21,8 +21,13 @@
#include "RigReservoirGridTools.h"
#include "Rim3dView.h"
#include "RimCase.h"
#include "RimEclipseCase.h"
#include "RimGeoMechCase.h"
#include "RimTools.h"
#include "RimViewController.h"
#include "cafPdmUiComboBoxEditor.h"
#include "cvfStructGridGeometryGenerator.h"
namespace caf
@ -52,9 +57,14 @@ RimCellFilter::RimCellFilter( FilterDefinitionType defType )
CAF_PDM_InitField( &m_isActive, "Active", true, "Active" );
m_isActive.uiCapability()->setUiHidden( true );
CAF_PDM_InitFieldNoDefault( &m_srcCase, "Case", "Case" );
m_srcCase.uiCapability()->setUiHidden( true );
CAF_PDM_InitFieldNoDefault( &m_filterMode, "FilterType", "Filter Type" );
CAF_PDM_InitField( &m_gridIndex, "GridIndex", 0, "Grid" );
m_gridIndex.uiCapability()->setUiEditorTypeName( caf::PdmUiComboBoxEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_propagateToSubGrids, "PropagateToSubGrids", true, "Apply to Subgrids" );
CAF_PDM_InitFieldNoDefault( &m_nameProxy, "NameProxy", "Name Proxy" );
@ -147,6 +157,30 @@ bool RimCellFilter::isIndexFilter() const
return m_filterDefinitionType == FilterDefinitionType::INDEX;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCellFilter::setCase( RimCase* srcCase )
{
m_srcCase = srcCase;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEclipseCase* RimCellFilter::eclipseCase() const
{
return dynamic_cast<RimEclipseCase*>( m_srcCase() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechCase* RimCellFilter::geoMechCase() const
{
return dynamic_cast<RimGeoMechCase*>( m_srcCase() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -226,6 +260,11 @@ void RimCellFilter::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
uiOrdering.add( &m_name );
auto group = uiOrdering.addNewGroup( "General" );
group->add( &m_filterMode );
if ( geoMechCase() != nullptr )
{
m_gridIndex.uiCapability()->setUiName( "Part" );
}
group->add( &m_gridIndex );
bool readOnlyState = isFilterControlled();
@ -269,27 +308,12 @@ QList<caf::PdmOptionItemInfo> RimCellFilter::calculateValueOptions( const caf::P
{
QList<caf::PdmOptionItemInfo> options;
if ( &m_gridIndex == fieldNeedingOptions )
if ( fieldNeedingOptions == &m_gridIndex )
{
auto rimCase = firstAncestorOrThisOfTypeAsserted<RimCase>();
for ( int gIdx = 0; gIdx < RigReservoirGridTools::gridCount( rimCase ); ++gIdx )
{
QString gridName;
gridName += RigReservoirGridTools::gridName( rimCase, gIdx );
if ( gIdx == 0 )
{
if ( gridName.isEmpty() )
gridName += "Main Grid";
else
gridName += " (Main Grid)";
}
caf::PdmOptionItemInfo item( gridName, (int)gIdx );
options.push_back( item );
}
RimTools::eclipseGridOptionItems( &options, eclipseCase() );
RimTools::geoMechPartOptionItems( &options, geoMechCase() );
}
return options;
}

View File

@ -22,6 +22,7 @@
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmProxyValueField.h"
#include "cafPdmPtrField.h"
#include "cafSignal.h"
#include "cvfArray.h"
@ -32,6 +33,10 @@ class StructGridInterface;
class CellRangeFilter;
} // namespace cvf
class RimGeoMechCase;
class RimEclipseCase;
class RimCase;
//==================================================================================================
///
///
@ -65,6 +70,8 @@ public:
bool isActive() const;
void setActive( bool active );
virtual void setCase( RimCase* srcCase );
bool isRangeFilter() const;
bool isIndexFilter() const;
@ -91,6 +98,9 @@ protected:
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
bool isFilterControlled() const;
RimGeoMechCase* geoMechCase() const;
RimEclipseCase* eclipseCase() const;
const cvf::StructGridInterface* selectedGrid() const;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
@ -101,6 +111,7 @@ protected:
caf::PdmField<caf::AppEnum<FilterModeType>> m_filterMode;
caf::PdmField<int> m_gridIndex;
caf::PdmField<bool> m_propagateToSubGrids;
caf::PdmPtrField<RimCase*> m_srcCase;
private:
FilterDefinitionType m_filterDefinitionType;

View File

@ -21,6 +21,7 @@
#include "Rim3dView.h"
#include "RimCase.h"
#include "RimCellFilter.h"
#include "RimCellIndexFilter.h"
#include "RimCellRangeFilter.h"
#include "RimPolygonFilter.h"
#include "RimUserDefinedFilter.h"
@ -94,8 +95,7 @@ void RimCellFilterCollection::setCase( RimCase* theCase )
{
for ( RimCellFilter* filter : m_cellFilters )
{
RimPolygonFilter* polyFilter = dynamic_cast<RimPolygonFilter*>( filter );
if ( polyFilter ) polyFilter->setCase( theCase );
filter->setCase( theCase );
}
}
@ -125,8 +125,10 @@ void RimCellFilterCollection::initAfterRead()
m_cellFilters.push_back( filter );
}
auto rimCase = firstAncestorOrThisOfTypeAsserted<RimCase>();
for ( const auto& filter : m_cellFilters )
{
filter->setCase( rimCase );
filter->filterChanged.connect( this, &RimCellFilterCollection::onFilterUpdated );
}
}
@ -266,6 +268,7 @@ RimPolygonFilter* RimCellFilterCollection::addNewPolygonFilter( RimCase* srcCase
RimUserDefinedFilter* RimCellFilterCollection::addNewUserDefinedFilter( RimCase* srcCase )
{
RimUserDefinedFilter* pFilter = new RimUserDefinedFilter();
pFilter->setCase( srcCase );
addFilter( pFilter );
onFilterUpdated( pFilter );
return pFilter;
@ -277,6 +280,7 @@ RimUserDefinedFilter* RimCellFilterCollection::addNewUserDefinedFilter( RimCase*
RimCellRangeFilter* RimCellFilterCollection::addNewCellRangeFilter( RimCase* srcCase, int gridIndex, int sliceDirection, int defaultSlice )
{
RimCellRangeFilter* pFilter = new RimCellRangeFilter();
pFilter->setCase( srcCase );
addFilter( pFilter );
pFilter->setGridIndex( gridIndex );
pFilter->setDefaultValues( sliceDirection, defaultSlice );
@ -284,6 +288,18 @@ RimCellRangeFilter* RimCellFilterCollection::addNewCellRangeFilter( RimCase* src
return pFilter;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimCellIndexFilter* RimCellFilterCollection::addNewCellIndexFilter( RimCase* srcCase )
{
RimCellIndexFilter* pFilter = new RimCellIndexFilter();
pFilter->setCase( srcCase );
addFilter( pFilter );
onFilterUpdated( pFilter );
return pFilter;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -303,12 +319,14 @@ void RimCellFilterCollection::setAutoName( RimCellFilter* pFilter )
int nPolyFilters = 1;
int nRangeFilters = 1;
int nUserFilters = 1;
int nIndexFilters = 1;
for ( RimCellFilter* filter : m_cellFilters )
{
if ( dynamic_cast<RimCellRangeFilter*>( filter ) ) nRangeFilters++;
if ( dynamic_cast<RimUserDefinedFilter*>( filter ) ) nUserFilters++;
if ( dynamic_cast<RimPolygonFilter*>( filter ) ) nPolyFilters++;
if ( dynamic_cast<RimCellIndexFilter*>( filter ) ) nIndexFilters++;
}
if ( dynamic_cast<RimCellRangeFilter*>( pFilter ) )
{
@ -322,6 +340,10 @@ void RimCellFilterCollection::setAutoName( RimCellFilter* pFilter )
{
pFilter->setName( QString( "Polygon Filter %1" ).arg( QString::number( nPolyFilters ) ) );
}
else if ( dynamic_cast<RimCellIndexFilter*>( pFilter ) )
{
pFilter->setName( QString( "Index Filter %1" ).arg( QString::number( nIndexFilters ) ) );
}
}
//--------------------------------------------------------------------------------------------------

View File

@ -26,6 +26,7 @@
#include "cvfArray.h"
class RimCellFilter;
class RimCellIndexFilter;
class RimCellRangeFilter;
class RimPolygonFilter;
class RimUserDefinedFilter;
@ -53,6 +54,7 @@ public:
RimPolygonFilter* addNewPolygonFilter( RimCase* srcCase );
RimUserDefinedFilter* addNewUserDefinedFilter( RimCase* srcCase );
RimCellRangeFilter* addNewCellRangeFilter( RimCase* srcCase, int gridIndex, int sliceDirection = -1, int defaultSlice = -1 );
RimCellIndexFilter* addNewCellIndexFilter( RimCase* srcCase );
void removeFilter( RimCellFilter* filter );

View File

@ -0,0 +1,180 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RimCellIndexFilter.h"
#include "RimGeoMechCase.h"
#include "RimTools.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigGeoMechCaseData.h"
#include "cafPdmUiComboBoxEditor.h"
CAF_PDM_SOURCE_INIT( RimCellIndexFilter, "CellIndexFilter" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimCellIndexFilter::RimCellIndexFilter()
: RimCellFilter( RimCellFilter::INDEX )
{
CAF_PDM_InitObject( "Cell Index Filter", ":/CellFilter_UserDefined.png" );
CAF_PDM_InitField( &m_setId, "ElementSetId", 0, "Element Set" );
m_setId.uiCapability()->setUiEditorTypeName( caf::PdmUiComboBoxEditor::uiEditorTypeName() );
m_propagateToSubGrids = true;
updateIconState();
setDeletable( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimCellIndexFilter::~RimCellIndexFilter()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimCellIndexFilter::fullName() const
{
return QString( "%1 [%2 cells]" ).arg( RimCellFilter::fullName(), QString::number( m_cells.size() ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCellIndexFilter::updateCellIndexFilter( cvf::UByteArray* includeVisibility, cvf::UByteArray* excludeVisibility, int gridIndex )
{
if ( gridIndex != m_gridIndex() ) return;
if ( m_cells.size() == 0 )
{
updateCells();
}
if ( m_filterMode == FilterModeType::INCLUDE )
{
for ( auto cellIdx : m_cells )
{
( *includeVisibility )[cellIdx] = true;
}
}
else
{
for ( auto cellIdx : m_cells )
{
( *excludeVisibility )[cellIdx] = false;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCellIndexFilter::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
{
if ( changedField == &m_gridIndex )
{
m_setId = 0;
}
if ( changedField != &m_name )
{
updateCells();
filterChanged.send();
updateIconState();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCellIndexFilter::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
m_gridIndex.uiCapability()->setUiName( "Part" );
auto group = uiOrdering.addNewGroup( "General" );
group->add( &m_gridIndex );
group->add( &m_setId );
group->add( &m_filterMode );
uiOrdering.skipRemainingFields( true );
bool readOnlyState = isFilterControlled();
std::vector<caf::PdmFieldHandle*> objFields = fields();
for ( auto& objField : objFields )
{
objField->uiCapability()->setUiReadOnly( readOnlyState );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimCellIndexFilter::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
{
QList<caf::PdmOptionItemInfo> options = RimCellFilter::calculateValueOptions( fieldNeedingOptions );
if ( fieldNeedingOptions == &m_setId )
{
RimTools::geoMechElementSetOptionItems( &options, geoMechCase(), m_gridIndex() );
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCellIndexFilter::updateCells()
{
m_cells.clear();
auto gCase = geoMechCase();
if ( gCase && gCase->geoMechData() && gCase->geoMechData()->femParts() )
{
auto parts = gCase->geoMechData()->femParts();
auto part = parts->part( m_gridIndex() );
auto setNames = part->elementSetNames();
if ( m_setId() < (int)setNames.size() )
{
m_name = QString::fromStdString( part->elementSetNames()[m_setId] );
}
else
{
m_name = QString::fromStdString( part->name() );
}
auto cells = part->elementSet( m_setId() );
for ( auto c : cells )
{
m_cells.push_back( c );
}
}
}

View File

@ -0,0 +1,52 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimCellFilter.h"
#include "cafPdmField.h"
#include "cafPdmPtrField.h"
class RimCase;
class RimGeoMechCase;
class RimCellIndexFilter : public RimCellFilter
{
CAF_PDM_HEADER_INIT;
public:
RimCellIndexFilter();
~RimCellIndexFilter() override;
void updateCellIndexFilter( cvf::UByteArray* includeVisibility, cvf::UByteArray* excludeVisibility, int gridIndex ) override;
protected:
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
QString fullName() const override;
void updateCells();
private:
std::vector<size_t> m_cells;
caf::PdmField<int> m_setId;
};

View File

@ -25,6 +25,7 @@
#include "RigReservoirGridTools.h"
#include "Rim3dView.h"
#include "RimCase.h"
#include "RimTools.h"
#include "cafPdmUiLabelEditor.h"
#include "cafPdmUiSliderEditor.h"
@ -178,9 +179,8 @@ void RimCellRangeFilter::setDefaultValues( int sliceDirection, int defaultSlice
auto rimView = firstAncestorOrThisOfType<Rim3dView>();
auto actCellInfo = RigReservoirGridTools::activeCellInfo( rimView );
auto rimCase = firstAncestorOrThisOfTypeAsserted<RimCase>();
const cvf::StructGridInterface* mainGrid = RigReservoirGridTools::mainGrid( rimCase );
const cvf::StructGridInterface* mainGrid = RigReservoirGridTools::mainGrid( m_srcCase );
if ( grid == mainGrid && actCellInfo )
{
@ -271,12 +271,9 @@ void RimCellRangeFilter::defineUiOrdering( QString uiConfigName, caf::PdmUiOrder
{
RimCellFilter::defineUiOrdering( uiConfigName, uiOrdering );
m_gridIndex.uiCapability()->setUiReadOnly( true );
const cvf::StructGridInterface* grid = selectedGrid();
auto rimCase = firstAncestorOrThisOfTypeAsserted<RimCase>();
const cvf::StructGridInterface* mainGrid = RigReservoirGridTools::mainGrid( rimCase );
const cvf::StructGridInterface* mainGrid = RigReservoirGridTools::mainGrid( m_srcCase );
auto rimView = firstAncestorOrThisOfType<Rim3dView>();
auto actCellInfo = RigReservoirGridTools::activeCellInfo( rimView );

View File

@ -60,10 +60,11 @@ public:
void updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter, int gridIndex ) override;
protected:
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override;
QString fullName() const override;
private:

View File

@ -139,9 +139,6 @@ RimPolygonFilter::RimPolygonFilter()
m_targets.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
m_targets.uiCapability()->setCustomContextMenuEnabled( true );
CAF_PDM_InitFieldNoDefault( &m_srcCase, "Case", "Case" );
m_srcCase.uiCapability()->setUiHidden( true );
CAF_PDM_InitField( &m_showLines, "ShowLines", true, "Show Lines" );
CAF_PDM_InitField( &m_showSpheres, "ShowSpheres", false, "Show Spheres" );
@ -204,14 +201,6 @@ void RimPolygonFilter::updateEditorsAndVisualization()
updateVisualization();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPolygonFilter::setCase( RimCase* srcCase )
{
m_srcCase = srcCase;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -840,8 +829,8 @@ void RimPolygonFilter::updateCells()
// make sure first and last point is the same (req. by polygon methods used later)
points.push_back( points.front() );
RimEclipseCase* eCase = dynamic_cast<RimEclipseCase*>( m_srcCase() );
RimGeoMechCase* gCase = dynamic_cast<RimGeoMechCase*>( m_srcCase() );
RimEclipseCase* eCase = eclipseCase();
RimGeoMechCase* gCase = geoMechCase();
if ( eCase )
{

View File

@ -73,7 +73,6 @@ public:
RimPolygonFilter();
~RimPolygonFilter() override;
void setCase( RimCase* srcCase );
void enableFilter( bool bEnable );
void enableKFilter( bool bEnable );
@ -123,7 +122,6 @@ private:
caf::PdmChildArrayField<RimPolylineTarget*> m_targets;
caf::PdmField<caf::AppEnum<PolygonFilterModeType>> m_polyFilterMode;
caf::PdmField<caf::AppEnum<PolygonIncludeType>> m_polyIncludeType;
caf::PdmPtrField<RimCase*> m_srcCase;
caf::PdmField<bool> m_enableFiltering;
caf::PdmField<bool> m_showLines;
caf::PdmField<bool> m_showSpheres;

View File

@ -1035,6 +1035,7 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
{
menuBuilder << "RicNewPolygonFilterFeature";
menuBuilder << "RicNewUserDefinedFilterFeature";
menuBuilder << "RicNewCellIndexFilterFeature";
menuBuilder << "Separator";
menuBuilder << "RicNewCellRangeFilterFeature";
menuBuilder.subMenuStart( "Slice Filters" );

View File

@ -20,6 +20,11 @@
#include "RimTools.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigGeoMechCaseData.h"
#include "RigReservoirGridTools.h"
#include "RimCase.h"
#include "RimColorLegend.h"
#include "RimColorLegendCollection.h"
@ -375,6 +380,74 @@ void RimTools::geoMechCaseOptionItems( QList<caf::PdmOptionItemInfo>* options )
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTools::eclipseGridOptionItems( QList<caf::PdmOptionItemInfo>* options, RimEclipseCase* eCase )
{
if ( !options ) return;
for ( int gIdx = 0; gIdx < RigReservoirGridTools::gridCount( eCase ); gIdx++ )
{
QString gridName = RigReservoirGridTools::gridName( eCase, gIdx );
if ( gIdx == 0 )
{
if ( gridName.isEmpty() )
gridName += "Main Grid";
else
gridName += " (Main Grid)";
}
options->push_back( caf::PdmOptionItemInfo( gridName, gIdx ) );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTools::geoMechPartOptionItems( QList<caf::PdmOptionItemInfo>* options, RimGeoMechCase* gCase )
{
if ( !options ) return;
if ( !gCase || !gCase->geoMechData() || !gCase->geoMechData()->femParts() ) return;
const auto parts = gCase->geoMechData()->femParts();
for ( int i = 0; i < parts->partCount(); i++ )
{
auto part = parts->part( i );
if ( part != nullptr )
{
options->push_back( caf::PdmOptionItemInfo( QString::fromStdString( part->name() ), i ) );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTools::geoMechElementSetOptionItems( QList<caf::PdmOptionItemInfo>* options, RimGeoMechCase* gCase, int partId )
{
if ( !options ) return;
if ( !gCase || !gCase->geoMechData() || !gCase->geoMechData()->femParts() ) return;
const auto parts = gCase->geoMechData()->femParts();
if ( partId >= parts->partCount() ) return;
auto part = parts->part( partId );
if ( part != nullptr )
{
auto names = part->elementSetNames();
for ( int i = 0; i < (int)names.size(); i++ )
{
options->push_back( caf::PdmOptionItemInfo( QString::fromStdString( names[i] ), i ) );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -34,6 +34,8 @@ namespace caf
class PdmOptionItemInfo;
}
class RimGeoMechCase;
class RimEclipseCase;
class RimWellPathCollection;
class RimCase;
class RimWellPath;
@ -59,7 +61,10 @@ public:
static void wellPathWithFormations( std::vector<RimWellPath*>* wellPaths );
static void caseOptionItems( QList<caf::PdmOptionItemInfo>* options );
static void eclipseCaseOptionItems( QList<caf::PdmOptionItemInfo>* options );
static void eclipseGridOptionItems( QList<caf::PdmOptionItemInfo>* options, RimEclipseCase* eCase );
static void geoMechCaseOptionItems( QList<caf::PdmOptionItemInfo>* options );
static void geoMechPartOptionItems( QList<caf::PdmOptionItemInfo>* options, RimGeoMechCase* gCase );
static void geoMechElementSetOptionItems( QList<caf::PdmOptionItemInfo>* options, RimGeoMechCase* gCase, int partId );
static void colorLegendOptionItems( QList<caf::PdmOptionItemInfo>* options );
static void seismicDataOptionItems( QList<caf::PdmOptionItemInfo>* options, cvf::BoundingBox worldBBox, bool basicDataOnly = false );
static void seismicDataOptionItems( QList<caf::PdmOptionItemInfo>* options );

View File

@ -1003,15 +1003,7 @@ QList<caf::PdmOptionItemInfo> RimWellLogExtractionCurve::calculateValueOptions(
}
else if ( fieldNeedingOptions == &m_geomPartId && m_case )
{
RimGeoMechCase* geomCase = dynamic_cast<RimGeoMechCase*>( m_case.value() );
if ( !geomCase || !geomCase->geoMechData() || !geomCase->geoMechData()->femParts() ) return options;
const auto femParts = geomCase->geoMechData()->femParts();
for ( int i = 0; i < femParts->partCount(); ++i )
{
const auto name = femParts->part( i )->name();
options.push_back( caf::PdmOptionItemInfo( QString::fromStdString( name ), i ) );
}
RimTools::geoMechPartOptionItems( &options, dynamic_cast<RimGeoMechCase*>( m_case.value() ) );
}
else if ( fieldNeedingOptions == &m_simWellName )
{