Add fault reactivation modeling

This commit is contained in:
jonjenssen 2023-05-03 02:20:05 +02:00 committed by Kristian Bendiksen
parent 14c37c4b2c
commit 32326bfa9b
43 changed files with 2626 additions and 157 deletions

View File

@ -42,6 +42,10 @@ RiaPreferencesGeoMech::RiaPreferencesGeoMech()
m_geomechWIACommand.uiCapability()->setUiEditorTypeName( caf::PdmUiFilePathEditor::uiEditorTypeName() );
m_geomechWIACommand.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
CAF_PDM_InitFieldNoDefault( &m_geomechFRMCommand, "geomechFRMCommand", "Command to run" );
m_geomechFRMCommand.uiCapability()->setUiEditorTypeName( caf::PdmUiFilePathEditor::uiEditorTypeName() );
m_geomechFRMCommand.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
CAF_PDM_InitField( &m_keepTemporaryFiles, "keepTemporaryFile", false, "Keep temporary parameter files (for debugging)" );
caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_keepTemporaryFiles );
@ -65,17 +69,13 @@ void RiaPreferencesGeoMech::appendItems( caf::PdmUiOrdering& uiOrdering ) const
caf::PdmUiGroup* wellIAGroup = uiOrdering.addNewGroup( "Well Integrity Analysis" );
wellIAGroup->add( &m_geomechWIACommand );
wellIAGroup->add( &m_geomechWIADefaultXML );
wellIAGroup->add( &m_waitForInputFileEdit );
caf::PdmUiGroup* faultRMGroup = uiOrdering.addNewGroup( "Fault Re-activation Modeling" );
faultRMGroup->add( &m_geomechFRMCommand );
caf::PdmUiGroup* commonGroup = uiOrdering.addNewGroup( "Common Settings" );
commonGroup->add( &m_keepTemporaryFiles );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaPreferencesGeoMech::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
commonGroup->add( &m_waitForInputFileEdit );
}
//--------------------------------------------------------------------------------------------------
@ -94,6 +94,14 @@ QString RiaPreferencesGeoMech::geomechWIADefaultXML() const
return m_geomechWIADefaultXML;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaPreferencesGeoMech::geomechFRMCommand() const
{
return m_geomechFRMCommand;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -105,7 +113,7 @@ bool RiaPreferencesGeoMech::keepTemporaryFiles() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaPreferencesGeoMech::waitBeforeRunWIA() const
bool RiaPreferencesGeoMech::waitBeforeRun() const
{
return m_waitForInputFileEdit;
}
@ -122,6 +130,17 @@ bool RiaPreferencesGeoMech::validateWIASettings() const
return filesExists( files );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaPreferencesGeoMech::validateFRMSettings() const
{
QStringList files;
files << geomechFRMCommand();
return filesExists( files );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -37,23 +37,25 @@ public:
void appendItems( caf::PdmUiOrdering& uiOrdering ) const;
bool validateWIASettings() const;
bool validateFRMSettings() const;
// geomech settings
QString geomechWIADefaultXML() const;
QString geomechWIACommand() const;
bool waitBeforeRunWIA() const;
QString geomechFRMCommand() const;
bool waitBeforeRun() const;
bool keepTemporaryFiles() const;
protected:
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
private:
bool filesExists( QStringList& filelist ) const;
caf::PdmField<QString> m_geomechWIADefaultXML;
caf::PdmField<QString> m_geomechWIACommand;
caf::PdmField<bool> m_waitForInputFileEdit;
caf::PdmField<QString> m_geomechFRMCommand;
caf::PdmField<bool> m_waitForInputFileEdit;
caf::PdmField<bool> m_keepTemporaryFiles;
};

View File

@ -148,6 +148,7 @@ list(
ProjectDataModelCommands/CommandRouter/CMakeLists_files.cmake
GeoMech/GeoMechVisualization/CMakeLists_files.cmake
ModelVisualization/CMakeLists_files.cmake
ModelVisualization/Faults/CMakeLists_files.cmake
ModelVisualization/GridBox/CMakeLists_files.cmake
ModelVisualization/Intersections/CMakeLists_files.cmake
ModelVisualization/Seismic/CMakeLists_files.cmake
@ -395,6 +396,7 @@ target_include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/FileInterface
${CMAKE_CURRENT_SOURCE_DIR}/GeoMech
${CMAKE_CURRENT_SOURCE_DIR}/ModelVisualization
${CMAKE_CURRENT_SOURCE_DIR}/ModelVisualization/Faults
${CMAKE_CURRENT_SOURCE_DIR}/ModelVisualization/GridBox
${CMAKE_CURRENT_SOURCE_DIR}/ModelVisualization/Intersections
${CMAKE_CURRENT_SOURCE_DIR}/ModelVisualization/Seismic

View File

@ -18,14 +18,9 @@
#include "RicEclipseHideFaultFeature.h"
#include "RicEclipsePropertyFilterFeatureImpl.h"
#include "RicEclipsePropertyFilterNewExec.h"
#include "RiaApplication.h"
#include "Rim3dView.h"
#include "RimEclipseCellColors.h"
#include "RimEclipsePropertyFilterCollection.h"
#include "RimEclipseView.h"
#include "RimFaultInView.h"
#include "RimFaultInViewCollection.h"
@ -33,9 +28,6 @@
#include "RigFault.h"
#include "RigMainGrid.h"
#include "cafCmdExecCommandManager.h"
#include "cvfStructGrid.h"
#include <QAction>
CAF_CMD_SOURCE_INIT( RicEclipseHideFaultFeature, "RicEclipseHideFaultFeature" );

View File

@ -18,14 +18,9 @@
#include "RicEclipseShowOnlyFaultFeature.h"
#include "RicEclipsePropertyFilterFeatureImpl.h"
#include "RicEclipsePropertyFilterNewExec.h"
#include "RiaApplication.h"
#include "Rim3dView.h"
#include "RimEclipseCellColors.h"
#include "RimEclipsePropertyFilterCollection.h"
#include "RimEclipseView.h"
#include "RimFaultInView.h"
#include "RimFaultInViewCollection.h"
@ -33,9 +28,7 @@
#include "RigFault.h"
#include "RigMainGrid.h"
#include "cafCmdExecCommandManager.h"
#include "cafPdmUiObjectHandle.h"
#include "cvfStructGrid.h"
#include <QAction>

View File

@ -10,6 +10,7 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RicImportGeoMechCaseTimeStepFilterFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicNewWellIntegrityAnalysisFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicRunWellIntegrityAnalysisFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicNewFaultReactModelingFeature.h
)
set(SOURCE_GROUP_SOURCE_FILES
@ -24,6 +25,7 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RicImportGeoMechCaseTimeStepFilterFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicNewWellIntegrityAnalysisFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicRunWellIntegrityAnalysisFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicNewFaultReactModelingFeature.cpp
)
list(APPEND COMMAND_CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})

View File

@ -0,0 +1,123 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- Statoil 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 "RicNewFaultReactModelingFeature.h"
#include "RiaApplication.h"
#include "RiaPreferencesGeoMech.h"
#include "Riu3DMainWindowTools.h"
#include "RiuViewer.h"
#include "Rim3dView.h"
#include "RimCase.h"
#include "RimEclipseView.h"
#include "RimFaultInView.h"
#include "RimFaultInViewCollection.h"
#include "RimFaultReactivationModel.h"
#include "RimFaultReactivationModelCollection.h"
#include "RigFault.h"
#include "RigMainGrid.h"
#include "cafCmdExecCommandManager.h"
#include "cafDisplayCoordTransform.h"
#include "cvfCamera.h"
#include "cvfStructGrid.h"
#include <QAction>
CAF_CMD_SOURCE_INIT( RicNewFaultReactModelingFeature, "RicNewFaultReactModelingFeature" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicNewFaultReactModelingFeature::isCommandEnabled() const
{
return RiaPreferencesGeoMech::current()->validateFRMSettings();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicNewFaultReactModelingFeature::onActionTriggered( bool isChecked )
{
QVariant userData = this->userData();
if ( !userData.isNull() && userData.type() == QVariant::List )
{
Rim3dView* view = RiaApplication::instance()->activeMainOrComparisonGridView();
if ( !view ) return;
RimEclipseView* eclView = dynamic_cast<RimEclipseView*>( view );
if ( !eclView ) return;
QVariantList list = userData.toList();
CAF_ASSERT( list.size() == 2 );
size_t currentCellIndex = static_cast<size_t>( list[0].toULongLong() );
int currentFaceIndex = list[1].toInt();
auto face = cvf::StructGridInterface::FaceType( currentFaceIndex );
const RigFault* fault = eclView->mainGrid()->findFaultFromCellIndexAndCellFace( currentCellIndex, face );
if ( fault )
{
QString faultName = fault->name();
RimFaultInView* rimFault = eclView->faultCollection()->findFaultByName( faultName );
if ( rimFault )
{
RigCell cell = eclView->mainGrid()->cell( currentCellIndex );
auto normal = cell.faceNormalWithAreaLength( face );
normal.z() = normal.z() / eclView->scaleZ() / eclView->scaleZ();
normal.normalize();
normal *= eclView->ownerCase()->characteristicCellSize();
normal *= 3;
auto antiNormal = -1.0 * normal;
auto camPos = eclView->viewer()->mainCamera()->position();
auto target1 = cell.faceCenter( face );
auto candidate1 = target1 + normal;
auto candidate2 = target1 + antiNormal;
auto target2 = candidate1;
if ( camPos.pointDistance( candidate2 ) < camPos.pointDistance( candidate1 ) ) target2 = candidate2;
RimFaultReactivationModel* model = eclView->faultReactivationModelCollection()->addNewModel( rimFault, target1, target2 );
if ( model != nullptr )
{
view->updateAllRequiredEditors();
Riu3DMainWindowTools::selectAsCurrentItem( model );
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicNewFaultReactModelingFeature::setupActionLook( QAction* actionToSetup )
{
actionToSetup->setIcon( QIcon( ":/fault_react_24x24.png" ) );
}

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 RicNewFaultReactModelingFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
protected:
bool isCommandEnabled() const override;
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
};

View File

@ -86,7 +86,7 @@ void RicRunWellIntegrityAnalysisFeature::onActionTriggered( bool isChecked )
return;
}
if ( RiaPreferencesGeoMech::current()->waitBeforeRunWIA() )
if ( RiaPreferencesGeoMech::current()->waitBeforeRun() )
{
runProgress.setProgressDescription( "Waiting for input file modifications." );

View File

@ -1,14 +1,11 @@
set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RivCellEdgeEffectGenerator.h
${CMAKE_CURRENT_LIST_DIR}/RivFaultPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivFaultGeometryGenerator.h
${CMAKE_CURRENT_LIST_DIR}/RivNNCGeometryGenerator.h
${CMAKE_CURRENT_LIST_DIR}/RivGridPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivTernarySaturationOverlayItem.h
${CMAKE_CURRENT_LIST_DIR}/RivReservoirPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivReservoirViewPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivPipeGeometryGenerator.h
${CMAKE_CURRENT_LIST_DIR}/RivReservoirFaultsPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivReservoirSimWellsPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivSourceInfo.h
${CMAKE_CURRENT_LIST_DIR}/RivWellPathSourceInfo.h
@ -64,12 +61,9 @@ set(SOURCE_GROUP_HEADER_FILES
set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RivCellEdgeEffectGenerator.cpp
${CMAKE_CURRENT_LIST_DIR}/RivFaultPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivNNCGeometryGenerator.cpp
${CMAKE_CURRENT_LIST_DIR}/RivFaultGeometryGenerator.cpp
${CMAKE_CURRENT_LIST_DIR}/RivGridPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivTernarySaturationOverlayItem.cpp
${CMAKE_CURRENT_LIST_DIR}/RivReservoirFaultsPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivReservoirPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivReservoirViewPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivPipeGeometryGenerator.cpp

View File

@ -0,0 +1,23 @@
set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RivFaultGeometryGenerator.h
${CMAKE_CURRENT_LIST_DIR}/RivFaultPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivReservoirFaultsPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivFaultReactivationModelPartMgr.h
)
set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RivFaultGeometryGenerator.cpp
${CMAKE_CURRENT_LIST_DIR}/RivFaultPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivReservoirFaultsPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivFaultReactivationModelPartMgr.cpp
)
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
list(APPEND CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES})
source_group(
"ModelVisualization\\Faults"
FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES}
${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake
)

View File

@ -0,0 +1,147 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RivFaultReactivationModelPartMgr.h"
#include "RiaGuiApplication.h"
#include "RigBasicPlane.h"
#include "RigFaultReactivationModel.h"
#include "RivPartPriority.h"
#include "RivPolylineGenerator.h"
#include "RivPolylinePartMgr.h"
#include "Rim3dView.h"
#include "RimFaultReactivationModel.h"
#include "cafDisplayCoordTransform.h"
#include "cafEffectGenerator.h"
#include "cafPdmObject.h"
#include "cvfLibCore.h"
#include "cvfLibGeometry.h"
#include "cvfLibRender.h"
#include "cvfModelBasicList.h"
#include "cvfPart.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivFaultReactivationModelPartMgr::RivFaultReactivationModelPartMgr( RimFaultReactivationModel* frm )
: m_frm( frm )
{
CVF_ASSERT( frm );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivFaultReactivationModelPartMgr::appendPolylinePartsToModel( Rim3dView* view,
cvf::ModelBasicList* vizModel,
const caf::DisplayCoordTransform* transform,
const cvf::BoundingBox& boundingBox )
{
if ( m_polylinePartMgr.isNull() ) m_polylinePartMgr = new RivPolylinePartMgr( view, m_frm.p(), m_frm.p() );
m_polylinePartMgr->appendDynamicGeometryPartsToModel( vizModel, transform, boundingBox );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivFaultReactivationModelPartMgr::appendMeshPartsToModel( Rim3dView* view,
cvf::ModelBasicList* vizModel,
const caf::DisplayCoordTransform* transform,
const cvf::BoundingBox& boundingBox )
{
auto model2d = m_frm->model();
if ( model2d.notNull() && model2d->isValid() && m_frm->isChecked() && m_frm->showModel() )
{
for ( auto gridPart : m_frm->model()->allGridParts() )
{
auto& lines = m_frm->model()->meshLines( gridPart );
std::vector<std::vector<cvf::Vec3d>> displayPoints;
for ( const auto& pts : lines )
{
displayPoints.push_back( transform->transformToDisplayCoords( pts ) );
}
cvf::ref<cvf::DrawableGeo> drawableGeo = RivPolylineGenerator::createSetOfLines( displayPoints );
cvf::ref<cvf::Part> part = new cvf::Part;
part->setName( "FaultReactMeshLines" );
part->setDrawable( drawableGeo.p() );
caf::MeshEffectGenerator effgen( cvf::Color3::LIGHT_GRAY );
effgen.setLineWidth( 1.5 );
effgen.setLineStipple( false );
cvf::ref<cvf::Effect> eff = effgen.generateCachedEffect();
part->setEffect( eff.p() );
part->setPriority( RivPartPriority::PartType::MeshLines );
vizModel->addPart( part.p() );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivFaultReactivationModelPartMgr::appendGeometryPartsToModel( cvf::ModelBasicList* vizModel,
const caf::DisplayCoordTransform* displayCoordTransform,
const cvf::BoundingBox& boundingBox )
{
if ( !m_canUseShaders ) return;
auto plane = m_frm->faultPlane();
if ( plane->isValid() && m_frm->showFaultPlane() )
{
cvf::Vec3dArray displayPoints;
displayPoints.reserve( plane->rect().size() );
for ( auto& vOrg : plane->rect() )
{
displayPoints.add( displayCoordTransform->transformToDisplayCoord( vOrg ) );
}
cvf::ref<cvf::Part> quadPart = createSingleTexturedQuadPart( displayPoints, plane->texture(), false );
vizModel->addPart( quadPart.p() );
}
auto theModel = m_frm->model();
if ( theModel->isValid() && m_frm->showModel() )
{
for ( auto part : theModel->allModelParts() )
{
cvf::Vec3dArray displayPoints;
displayPoints.reserve( theModel->rect( part ).size() );
for ( auto& vOrg : theModel->rect( part ) )
{
displayPoints.add( displayCoordTransform->transformToDisplayCoord( vOrg ) );
}
cvf::ref<cvf::Part> quadPart = createSingleTexturedQuadPart( displayPoints, theModel->texture( part ), false );
vizModel->addPart( quadPart.p() );
}
}
}

View File

@ -0,0 +1,67 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RivTexturePartMgr.h"
#include "cafPdmPointer.h"
#include "cvfArray.h"
#include "cvfObject.h"
namespace cvf
{
class ModelBasicList;
class Part;
class DrawableGeo;
class BoundingBox;
class TextureImage;
} // namespace cvf
namespace caf
{
class DisplayCoordTransform;
}
class RimFaultReactivationModel;
class Rim3dView;
class RivPolylinePartMgr;
class RivFaultReactivationModelPartMgr : public RivTexturePartMgr
{
public:
explicit RivFaultReactivationModelPartMgr( RimFaultReactivationModel* frm );
void appendGeometryPartsToModel( cvf::ModelBasicList* vizModel,
const caf::DisplayCoordTransform* displayCoordTransform,
const cvf::BoundingBox& boundingBox );
void appendPolylinePartsToModel( Rim3dView* view,
cvf::ModelBasicList* vizModel,
const caf::DisplayCoordTransform* displayCoordTransform,
const cvf::BoundingBox& boundingBox );
void appendMeshPartsToModel( Rim3dView* view,
cvf::ModelBasicList* vizModel,
const caf::DisplayCoordTransform* displayCoordTransform,
const cvf::BoundingBox& boundingBox );
private:
caf::PdmPointer<RimFaultReactivationModel> m_frm;
cvf::ref<RivPolylinePartMgr> m_polylinePartMgr;
};

View File

@ -120,3 +120,45 @@ cvf::ref<cvf::DrawableGeo> RivPolylineGenerator::createPointsFromPolylineDrawabl
return geo;
}
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivPolylineGenerator::createSetOfLines( const std::vector<std::vector<cvf::Vec3d>>& lines )
{
std::vector<cvf::uint> lineIndices;
std::vector<cvf::Vec3f> vertices;
for ( const std::vector<cvf::Vec3d>& polyLine : lines )
{
if ( polyLine.size() < 2 ) continue;
size_t verticesCount = vertices.size();
for ( size_t i = 0; i < polyLine.size(); i += 2 )
{
vertices.emplace_back( polyLine[i] );
vertices.emplace_back( polyLine[i + 1] );
if ( i < polyLine.size() - 1 )
{
lineIndices.push_back( static_cast<cvf::uint>( verticesCount + i ) );
lineIndices.push_back( static_cast<cvf::uint>( verticesCount + i + 1 ) );
}
}
}
if ( vertices.empty() ) return nullptr;
cvf::ref<cvf::Vec3fArray> vx = new cvf::Vec3fArray;
vx->assign( vertices );
cvf::ref<cvf::UIntArray> idxes = new cvf::UIntArray;
idxes->assign( lineIndices );
cvf::ref<cvf::PrimitiveSetIndexedUInt> prim = new cvf::PrimitiveSetIndexedUInt( cvf::PT_LINES );
prim->setIndices( idxes.p() );
cvf::ref<cvf::DrawableGeo> polylineGeo = new cvf::DrawableGeo;
polylineGeo->setVertexArray( vx.p() );
polylineGeo->addPrimitiveSet( prim.p() );
return polylineGeo;
}

View File

@ -40,4 +40,6 @@ public:
static cvf::ref<cvf::DrawableGeo> createPointsFromPolylineDrawable( const std::vector<cvf::Vec3d>& polyLine );
static cvf::ref<cvf::DrawableGeo> createPointsFromPolylineDrawable( const std::vector<std::vector<cvf::Vec3d>>& polyLines );
static cvf::ref<cvf::DrawableGeo> createSetOfLines( const std::vector<std::vector<cvf::Vec3d>>& lines );
};

View File

@ -1,11 +1,13 @@
set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RivSeismicSectionPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivSeismicSectionSourceInfo.h
${CMAKE_CURRENT_LIST_DIR}/RivTexturePartMgr.h
)
set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RivSeismicSectionPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivSeismicSectionSourceInfo.cpp
${CMAKE_CURRENT_LIST_DIR}/RivTexturePartMgr.cpp
)
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})

View File

@ -55,17 +55,8 @@
//--------------------------------------------------------------------------------------------------
RivSeismicSectionPartMgr::RivSeismicSectionPartMgr( RimSeismicSection* section )
: m_section( section )
, m_canUseShaders( true )
{
CVF_ASSERT( section );
m_canUseShaders = RiaGuiApplication::instance()->useShaders();
cvf::ShaderProgramGenerator gen( "Texturing", cvf::ShaderSourceProvider::instance() );
gen.addVertexCode( cvf::ShaderSourceRepository::vs_Standard );
gen.addFragmentCode( cvf::ShaderSourceRepository::src_Texture );
gen.addFragmentCode( cvf::ShaderSourceRepository::fs_Unlit );
m_textureShaderProg = gen.generate();
}
//--------------------------------------------------------------------------------------------------
@ -111,7 +102,7 @@ void RivSeismicSectionPartMgr::appendGeometryPartsToModel( cvf::ModelBasicList*
part.texture = createImageFromData( part.sliceData.get() );
}
cvf::ref<cvf::Part> quadPart = createSingleTexturedQuadPart( displayPoints, part.texture );
cvf::ref<cvf::Part> quadPart = createSingleTexturedQuadPart( displayPoints, part.texture, m_section->isTransparent() );
cvf::ref<RivSeismicSectionSourceInfo> si = new RivSeismicSectionSourceInfo( m_section, i );
quadPart->setSourceInfo( si.p() );
@ -120,85 +111,6 @@ void RivSeismicSectionPartMgr::appendGeometryPartsToModel( cvf::ModelBasicList*
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Part> RivSeismicSectionPartMgr::createSingleTexturedQuadPart( const cvf::Vec3dArray& cornerPoints,
cvf::ref<cvf::TextureImage> image )
{
cvf::ref<cvf::Part> part = new cvf::Part;
cvf::ref<cvf::DrawableGeo> geo = createXYPlaneQuadGeoWithTexCoords( cornerPoints );
cvf::ref<cvf::Texture> texture = new cvf::Texture( image.p() );
cvf::ref<cvf::Sampler> sampler = new cvf::Sampler;
sampler->setMinFilter( cvf::Sampler::LINEAR );
sampler->setMagFilter( cvf::Sampler::NEAREST );
sampler->setWrapModeS( cvf::Sampler::CLAMP_TO_EDGE );
sampler->setWrapModeT( cvf::Sampler::CLAMP_TO_EDGE );
cvf::ref<cvf::RenderStateTextureBindings> textureBindings = new cvf::RenderStateTextureBindings;
textureBindings->addBinding( texture.p(), sampler.p(), "u_texture2D" );
cvf::ref<cvf::Effect> eff = new cvf::Effect;
eff->setRenderState( textureBindings.p() );
eff->setShaderProgram( m_textureShaderProg.p() );
if ( m_section->isTransparent() )
{
part->setPriority( RivPartPriority::PartType::TransparentSeismic );
cvf::ref<cvf::RenderStateBlending> blending = new cvf::RenderStateBlending;
blending->configureTransparencyBlending();
eff->setRenderState( blending.p() );
}
part->setDrawable( geo.p() );
part->setEffect( eff.p() );
return part;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivSeismicSectionPartMgr::createXYPlaneQuadGeoWithTexCoords( const cvf::Vec3dArray& cornerPoints )
{
cvf::ref<cvf::Vec3fArray> vertices = new cvf::Vec3fArray;
vertices->reserve( 4 );
for ( const auto& v : cornerPoints )
{
vertices->add( cvf::Vec3f( v ) );
}
cvf::ref<cvf::Vec2fArray> texCoords = new cvf::Vec2fArray;
texCoords->reserve( 4 );
texCoords->add( cvf::Vec2f( 0, 0 ) );
texCoords->add( cvf::Vec2f( 1, 0 ) );
texCoords->add( cvf::Vec2f( 1, 1 ) );
texCoords->add( cvf::Vec2f( 0, 1 ) );
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
geo->setVertexArray( vertices.p() );
geo->setTextureCoordArray( texCoords.p() );
cvf::ref<cvf::UIntArray> indices = new cvf::UIntArray;
indices->reserve( 6 );
for ( uint i : { 0, 1, 2, 0, 2, 3 } )
{
indices->add( i );
}
cvf::ref<cvf::PrimitiveSetIndexedUInt> primSet = new cvf::PrimitiveSetIndexedUInt( cvf::PT_TRIANGLES );
primSet->setIndices( indices.p() );
geo->addPrimitiveSet( primSet.p() );
geo->computeNormals();
return geo;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -17,17 +17,15 @@
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RivTexturePartMgr.h"
#include "cafPdmPointer.h"
#include "cvfArray.h"
#include "cvfObject.h"
#include "cvfVector3.h"
namespace cvf
{
class ModelBasicList;
class Transform;
class Part;
class ScalarMapper;
class DrawableGeo;
class BoundingBox;
class ShaderProgram;
@ -44,13 +42,12 @@ namespace ZGYAccess
class SeismicSliceData;
}
class RimSeismicSectionCollection;
class RimSeismicSection;
class RimSurface;
class Rim3dView;
class RivPolylinePartMgr;
class RivSeismicSectionPartMgr : public cvf::Object
class RivSeismicSectionPartMgr : public RivTexturePartMgr
{
public:
explicit RivSeismicSectionPartMgr( RimSeismicSection* section );
@ -73,6 +70,7 @@ private:
cvf::ref<cvf::DrawableGeo> createXYPlaneQuadGeoWithTexCoords( const cvf::Vec3dArray& cornerPoints );
cvf::ref<cvf::Part> createSingleTexturedQuadPart( const cvf::Vec3dArray& cornerPoints, cvf::ref<cvf::TextureImage> image );
protected:
cvf::TextureImage* createImageFromData( ZGYAccess::SeismicSliceData* data );
static std::vector<std::vector<cvf::Vec3d>> projectPolyLineOntoSurface( std::vector<cvf::Vec3d> polyLine,
@ -82,7 +80,4 @@ private:
private:
caf::PdmPointer<RimSeismicSection> m_section;
cvf::ref<RivPolylinePartMgr> m_polylinePartMgr;
cvf::ref<cvf::ShaderProgram> m_textureShaderProg;
bool m_canUseShaders;
};

View File

@ -0,0 +1,137 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RivTexturePartMgr.h"
#include "RiaGuiApplication.h"
#include "RivPartPriority.h"
#include "RigTexturedSection.h"
#include "cafDisplayCoordTransform.h"
#include "cafEffectGenerator.h"
#include "cafPdmObject.h"
#include "cvfLibCore.h"
#include "cvfLibGeometry.h"
#include "cvfLibRender.h"
#include "cvfModelBasicList.h"
#include "cvfPart.h"
#include "cvfScalarMapper.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivTexturePartMgr::RivTexturePartMgr()
: m_canUseShaders( true )
{
m_canUseShaders = RiaGuiApplication::instance()->useShaders();
cvf::ShaderProgramGenerator gen( "Texturing", cvf::ShaderSourceProvider::instance() );
gen.addVertexCode( cvf::ShaderSourceRepository::vs_Standard );
gen.addFragmentCode( cvf::ShaderSourceRepository::src_Texture );
gen.addFragmentCode( cvf::ShaderSourceRepository::fs_Unlit );
m_textureShaderProg = gen.generate();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivTexturePartMgr::~RivTexturePartMgr()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Part>
RivTexturePartMgr::createSingleTexturedQuadPart( const cvf::Vec3dArray& cornerPoints, cvf::ref<cvf::TextureImage> image, bool transparent )
{
cvf::ref<cvf::Part> part = new cvf::Part;
cvf::ref<cvf::DrawableGeo> geo = createXYPlaneQuadGeoWithTexCoords( cornerPoints );
cvf::ref<cvf::Texture> texture = new cvf::Texture( image.p() );
cvf::ref<cvf::Sampler> sampler = new cvf::Sampler;
sampler->setMinFilter( cvf::Sampler::LINEAR );
sampler->setMagFilter( cvf::Sampler::NEAREST );
sampler->setWrapModeS( cvf::Sampler::CLAMP_TO_EDGE );
sampler->setWrapModeT( cvf::Sampler::CLAMP_TO_EDGE );
cvf::ref<cvf::RenderStateTextureBindings> textureBindings = new cvf::RenderStateTextureBindings;
textureBindings->addBinding( texture.p(), sampler.p(), "u_texture2D" );
cvf::ref<cvf::Effect> eff = new cvf::Effect;
eff->setRenderState( textureBindings.p() );
eff->setShaderProgram( m_textureShaderProg.p() );
if ( transparent )
{
part->setPriority( RivPartPriority::PartType::TransparentSeismic );
cvf::ref<cvf::RenderStateBlending> blending = new cvf::RenderStateBlending;
blending->configureTransparencyBlending();
eff->setRenderState( blending.p() );
}
part->setDrawable( geo.p() );
part->setEffect( eff.p() );
return part;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivTexturePartMgr::createXYPlaneQuadGeoWithTexCoords( const cvf::Vec3dArray& cornerPoints )
{
cvf::ref<cvf::Vec3fArray> vertices = new cvf::Vec3fArray;
vertices->reserve( 4 );
for ( const auto& v : cornerPoints )
{
vertices->add( cvf::Vec3f( v ) );
}
cvf::ref<cvf::Vec2fArray> texCoords = new cvf::Vec2fArray;
texCoords->reserve( 4 );
texCoords->add( cvf::Vec2f( 0, 0 ) );
texCoords->add( cvf::Vec2f( 1, 0 ) );
texCoords->add( cvf::Vec2f( 1, 1 ) );
texCoords->add( cvf::Vec2f( 0, 1 ) );
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
geo->setVertexArray( vertices.p() );
geo->setTextureCoordArray( texCoords.p() );
cvf::ref<cvf::UIntArray> indices = new cvf::UIntArray;
indices->reserve( 6 );
for ( uint i : { 0, 1, 2, 0, 2, 3 } )
{
indices->add( i );
}
cvf::ref<cvf::PrimitiveSetIndexedUInt> primSet = new cvf::PrimitiveSetIndexedUInt( cvf::PT_TRIANGLES );
primSet->setIndices( indices.p() );
geo->addPrimitiveSet( primSet.p() );
geo->computeNormals();
return geo;
}

View File

@ -0,0 +1,63 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "cafPdmPointer.h"
#include "cvfArray.h"
#include "cvfObject.h"
namespace cvf
{
class ModelBasicList;
class Part;
class DrawableGeo;
class BoundingBox;
class ShaderProgram;
class TextureImage;
} // namespace cvf
namespace caf
{
class DisplayCoordTransform;
}
class Rim3dView;
class RivTexturePartMgr : public cvf::Object
{
public:
RivTexturePartMgr();
virtual ~RivTexturePartMgr();
virtual void appendGeometryPartsToModel( cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform,
const cvf::BoundingBox& boundingBox ) = 0;
virtual void appendPolylinePartsToModel( Rim3dView* view,
cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform,
const cvf::BoundingBox& boundingBox ) = 0;
protected:
cvf::ref<cvf::DrawableGeo> createXYPlaneQuadGeoWithTexCoords( const cvf::Vec3dArray& cornerPoints );
cvf::ref<cvf::Part> createSingleTexturedQuadPart( const cvf::Vec3dArray& cornerPoints, cvf::ref<cvf::TextureImage> image, bool transparent );
cvf::ref<cvf::ShaderProgram> m_textureShaderProg;
bool m_canUseShaders;
};

View File

@ -1,11 +1,15 @@
set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RimFaultInView.h
${CMAKE_CURRENT_LIST_DIR}/RimFaultInViewCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationModel.h
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationModelCollection.h
)
set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RimFaultInView.cpp
${CMAKE_CURRENT_LIST_DIR}/RimFaultInViewCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationModel.cpp
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationModelCollection.cpp
)
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})

View File

@ -0,0 +1,450 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RimFaultReactivationModel.h"
#include "RiaApplication.h"
#include "RiaPreferencesGeoMech.h"
#include "RigBasicPlane.h"
#include "RigFaultReactivationModel.h"
#include "RigPolyLinesData.h"
#include "WellPathCommands/PointTangentManipulator/RicPolyline3dEditor.h"
#include "WellPathCommands/RicPolylineTargetsPickEventHandler.h"
#include "RiuViewer.h"
#include "RivFaultReactivationModelPartMgr.h"
#include "Rim3dView.h"
#include "RimEclipseCase.h"
#include "RimEclipseView.h"
#include "RimFaultInView.h"
#include "RimFaultInViewCollection.h"
#include "RimPolylineTarget.h"
#include "RimTools.h"
#include "cafPdmUiDoubleSliderEditor.h"
#include "cafPdmUiTableViewEditor.h"
#include "cvfPlane.h"
#include "cvfTextureImage.h"
CAF_PDM_SOURCE_INIT( RimFaultReactivationModel, "FaultReactivationModel" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFaultReactivationModel::RimFaultReactivationModel()
: m_pickTargetsEventHandler( new RicPolylineTargetsPickEventHandler( this ) )
{
CAF_PDM_InitObject( "Fault Reactivation Model", ":/fault_react_24x24.png" );
CAF_PDM_InitField( &m_userDescription, "UserDescription", QString( "Model" ), "Name" );
CAF_PDM_InitField( &m_extentHorizontal, "HorizontalExtent", 1000.0, "Horizontal Extent" );
CAF_PDM_InitField( &m_extentVerticalAbove, "VerticalExtentAbove", 200.0, "Vertical Extent Above Anchor" );
m_extentVerticalAbove.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() );
m_extentVerticalAbove.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosType::TOP );
CAF_PDM_InitField( &m_extentVerticalBelow, "VerticalExtentBelow", 200.0, "Vertical Extent Below Anchor" );
m_extentVerticalBelow.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() );
m_extentVerticalBelow.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosType::TOP );
CAF_PDM_InitField( &m_modelExtentFromAnchor, "ModelExtentFromAnchor", 1000.0, "Horz. Extent from Anchor" );
CAF_PDM_InitField( &m_modelMinZ, "ModelMinZ", 0.0, "Start Depth" );
CAF_PDM_InitField( &m_modelBelowSize, "ModelBelowSize", 500.0, "Depth Below Fault" );
CAF_PDM_InitField( &m_showFaultPlane, "ShowFaultPlane", true, "Show Fault Plane" );
CAF_PDM_InitField( &m_showModelPlane, "ShowModelPlane", false, "Show 2D Model" );
CAF_PDM_InitFieldNoDefault( &m_fault, "Fault", "Fault" );
m_fault.uiCapability()->setUiReadOnly( true );
CAF_PDM_InitField( &m_faultPlaneColor, "FaultPlaneColor", cvf::Color3f( cvf::Color3f::GRAY ), "Plane Color" );
CAF_PDM_InitField( &m_modelPart1Color, "ModelPart1Color", cvf::Color3f( cvf::Color3f::GREEN ), "Part 1 Color" );
CAF_PDM_InitField( &m_modelPart2Color, "ModelPart2Color", cvf::Color3f( cvf::Color3f::BLUE ), "Part 2 Color" );
CAF_PDM_InitField( &m_numberOfCellsHorzPart1, "NumberOfCellsHorzPart1", 20, "Horizontal Number of Cells, Part 1" );
CAF_PDM_InitField( &m_numberOfCellsHorzPart2, "NumberOfCellsHorzPart2", 20, "Horizontal Number of Cells, Part 2" );
CAF_PDM_InitField( &m_numberOfCellsVertUp, "NumberOfCellsVertUp", 20, "Vertical Number of Cells, Upper Part" );
CAF_PDM_InitField( &m_numberOfCellsVertMid, "NumberOfCellsVertMid", 20, "Vertical Number of Cells, Middle Part" );
CAF_PDM_InitField( &m_numberOfCellsVertLow, "NumberOfCellsVertLow", 20, "Vertical Number of Cells, Lower Part" );
CAF_PDM_InitFieldNoDefault( &m_targets, "Targets", "Targets" );
m_targets.uiCapability()->setUiEditorTypeName( caf::PdmUiTableViewEditor::uiEditorTypeName() );
m_targets.uiCapability()->setUiTreeChildrenHidden( true );
m_targets.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
m_targets.uiCapability()->setCustomContextMenuEnabled( false );
this->setUi3dEditorTypeName( RicPolyline3dEditor::uiEditorTypeName() );
this->uiCapability()->setUiTreeChildrenHidden( true );
setDeletable( true );
m_faultPlane = new RigBasicPlane();
m_modelPlane = new RigFaultReactivationModel();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFaultReactivationModel::~RimFaultReactivationModel()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModel::initAfterRead()
{
updateVisualization();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFaultReactivationModel::userDescription()
{
return m_userDescription;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModel::setUserDescription( QString description )
{
m_userDescription = description;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimFaultReactivationModel::userDescriptionField()
{
return &m_userDescription;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModel::setFault( RimFaultInView* fault )
{
m_fault = fault;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFaultInView* RimFaultReactivationModel::fault() const
{
return m_fault();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModel::setTargets( cvf::Vec3d target1, cvf::Vec3d target2 )
{
m_targets.deleteChildren();
RimPolylineTarget* planeCenter = new RimPolylineTarget();
planeCenter->setAsPointXYZ( target1 );
m_targets.push_back( planeCenter );
RimPolylineTarget* steeringTarget = new RimPolylineTarget();
steeringTarget->setAsPointXYZ( target2 );
m_targets.push_back( steeringTarget );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimPolylineTarget*> RimFaultReactivationModel::activeTargets() const
{
return m_targets.childrenByType();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModel::insertTarget( const RimPolylineTarget* targetToInsertBefore, RimPolylineTarget* targetToInsert )
{
// do nothing, we should only have 2 predefined targets
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModel::deleteTarget( RimPolylineTarget* targetToDelete )
{
// do nothing, we should always have 2 predefined targets
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimFaultReactivationModel::pickingEnabled() const
{
// never pick, we only have our 2 predefined targets
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PickEventHandler* RimFaultReactivationModel::pickEventHandler() const
{
return m_pickTargetsEventHandler.get();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModel::updateVisualization()
{
auto view = firstAncestorOrThisOfType<Rim3dView>();
if ( !view ) return;
auto normal = m_targets[1]->targetPointXYZ() - m_targets[0]->targetPointXYZ();
normal.z() = normal.z() * view->scaleZ() * view->scaleZ();
normal.normalize();
m_faultPlane->setPlane( m_targets[0]->targetPointXYZ(), normal );
m_faultPlane->setMaxExtentFromAnchor( m_extentHorizontal, m_extentVerticalAbove, m_extentVerticalBelow );
m_faultPlane->setColor( m_faultPlaneColor );
m_faultPlane->updateRect();
double maxZ = m_faultPlane->maxDepth();
auto [topInt, bottomInt] = m_faultPlane->intersectTopBottomLine();
cvf::Vec3d zdir( 0, 0, 1 );
auto modelNormal = normal ^ zdir;
modelNormal.normalize();
m_modelPlane->setPlane( m_targets[0]->targetPointXYZ(), modelNormal );
m_modelPlane->setFaultPlaneIntersect( topInt, bottomInt );
m_modelPlane->setMaxExtentFromAnchor( m_modelExtentFromAnchor, m_modelMinZ, maxZ + m_modelBelowSize );
m_modelPlane->setPartColors( m_modelPart1Color, m_modelPart2Color );
m_modelPlane->setCellCounts( m_numberOfCellsHorzPart1,
m_numberOfCellsHorzPart2,
m_numberOfCellsVertUp,
m_numberOfCellsVertMid,
m_numberOfCellsVertLow );
m_modelPlane->updateRects();
view->scheduleCreateDisplayModelAndRedraw();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModel::updateEditorsAndVisualization()
{
updateConnectedEditors();
updateVisualization();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<RigPolyLinesData> RimFaultReactivationModel::polyLinesData() const
{
cvf::ref<RigPolyLinesData> pld = new RigPolyLinesData;
std::vector<cvf::Vec3d> line;
for ( const RimPolylineTarget* target : m_targets )
{
line.push_back( target->targetPointXYZ() );
}
pld->setPolyLine( line );
return pld;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimFaultReactivationModel::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
{
QList<caf::PdmOptionItemInfo> options;
if ( fieldNeedingOptions == &m_fault )
{
if ( m_fault() != nullptr )
{
auto coll = m_fault->firstAncestorOrThisOfType<RimFaultInViewCollection>();
if ( coll != nullptr ) RimTools::faultOptionItems( &options, coll );
}
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivFaultReactivationModelPartMgr* RimFaultReactivationModel::partMgr()
{
if ( m_partMgr.isNull() ) m_partMgr = new RivFaultReactivationModelPartMgr( this );
return m_partMgr.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<RigBasicPlane> RimFaultReactivationModel::faultPlane() const
{
return m_faultPlane;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<RigFaultReactivationModel> RimFaultReactivationModel::model() const
{
return m_modelPlane;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimFaultReactivationModel::showFaultPlane() const
{
return m_showFaultPlane;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimFaultReactivationModel::showModel() const
{
return m_showModelPlane;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModel::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
auto genGrp = uiOrdering.addNewGroup( "General" );
genGrp->add( &m_userDescription );
genGrp->add( &m_fault );
auto faultGrp = uiOrdering.addNewGroup( "Fault Plane" );
faultGrp->add( &m_showFaultPlane );
faultGrp->add( &m_faultPlaneColor );
faultGrp->add( &m_extentHorizontal );
faultGrp->add( &m_extentVerticalAbove );
faultGrp->add( &m_extentVerticalBelow );
auto modelGrp = uiOrdering.addNewGroup( "2D Model" );
modelGrp->add( &m_showModelPlane );
auto sizeModelGrp = modelGrp->addNewGroup( "Size" );
sizeModelGrp->add( &m_modelExtentFromAnchor );
sizeModelGrp->add( &m_modelMinZ );
sizeModelGrp->add( &m_modelBelowSize );
auto gridModelGrp = modelGrp->addNewGroup( "Grid" );
gridModelGrp->add( &m_numberOfCellsHorzPart1 );
gridModelGrp->add( &m_numberOfCellsHorzPart2 );
gridModelGrp->add( &m_numberOfCellsVertUp );
gridModelGrp->add( &m_numberOfCellsVertMid );
gridModelGrp->add( &m_numberOfCellsVertLow );
auto appModelGrp = modelGrp->addNewGroup( "Appearance" );
appModelGrp->add( &m_modelPart1Color );
appModelGrp->add( &m_modelPart2Color );
auto trgGroup = uiOrdering.addNewGroup( "Debug" );
trgGroup->setCollapsedByDefault();
trgGroup->add( &m_targets );
uiOrdering.skipRemainingFields();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModel::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
{
if ( changedField == &m_userDescription )
{
updateConnectedEditors();
}
else
{
updateVisualization();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModel::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
{
if ( field == &m_targets )
{
auto tvAttribute = dynamic_cast<caf::PdmUiTableViewEditorAttribute*>( attribute );
if ( tvAttribute )
{
tvAttribute->resizePolicy = caf::PdmUiTableViewEditorAttribute::RESIZE_TO_FIT_CONTENT;
}
}
else if ( ( field == &m_extentVerticalAbove ) || ( field == &m_extentVerticalBelow ) )
{
auto* attr = dynamic_cast<caf::PdmUiDoubleSliderEditorAttribute*>( attribute );
if ( attr )
{
auto eclCase = eclipseCase();
if ( eclCase )
{
auto bb = eclCase->allCellsBoundingBox();
double diff = bb.max().z() - bb.min().z();
attr->m_minimum = 0;
attr->m_maximum = diff;
}
else
{
attr->m_minimum = 0;
attr->m_maximum = 1000;
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEclipseCase* RimFaultReactivationModel::eclipseCase()
{
auto activeView = dynamic_cast<RimEclipseView*>( RiaApplication::instance()->activeGridView() );
if ( activeView )
{
return activeView->eclipseCase();
}
return nullptr;
}

View File

@ -0,0 +1,130 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RimCheckableNamedObject.h"
#include "RimPolylinePickerInterface.h"
#include "RimPolylinesDataInterface.h"
#include "cafFilePath.h"
#include "cafPdmChildArrayField.h"
#include "cafPdmChildField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPtrField.h"
#include "cvfColor3.h"
#include "cvfVector3.h"
#include <QString>
#include <memory>
#include <utility>
class RicPolylineTargetsPickEventHandler;
class RimEclipseCase;
class RimFaultInView;
class RimPolylineTarget;
class RivFaultReactivationModelPartMgr;
class RigBasicPlane;
class RigFaultReactivationModel;
namespace cvf
{
class BoundingBox;
class Plane;
} // namespace cvf
class RimFaultReactivationModel : public RimCheckableNamedObject, public RimPolylinePickerInterface, public RimPolylinesDataInterface
{
CAF_PDM_HEADER_INIT;
public:
RimFaultReactivationModel();
~RimFaultReactivationModel() override;
QString userDescription();
void setUserDescription( QString description );
void setFault( RimFaultInView* fault );
RimFaultInView* fault() const;
void setTargets( cvf::Vec3d target1, cvf::Vec3d target2 );
RivFaultReactivationModelPartMgr* partMgr();
// polyline picker interface
void insertTarget( const RimPolylineTarget* targetToInsertBefore, RimPolylineTarget* targetToInsert ) override;
void deleteTarget( RimPolylineTarget* targetToDelete ) override;
void updateEditorsAndVisualization() override;
void updateVisualization() override;
std::vector<RimPolylineTarget*> activeTargets() const override;
bool pickingEnabled() const override;
caf::PickEventHandler* pickEventHandler() const override;
// polyline data interface
cvf::ref<RigPolyLinesData> polyLinesData() const override;
cvf::ref<RigBasicPlane> faultPlane() const;
bool showFaultPlane() const;
cvf::ref<RigFaultReactivationModel> model() const;
bool showModel() const;
protected:
caf::PdmFieldHandle* userDescriptionField() override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) 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;
RimEclipseCase* eclipseCase();
void initAfterRead() override;
private:
std::shared_ptr<RicPolylineTargetsPickEventHandler> m_pickTargetsEventHandler;
cvf::ref<RivFaultReactivationModelPartMgr> m_partMgr;
caf::PdmField<QString> m_userDescription;
caf::PdmPtrField<RimFaultInView*> m_fault;
caf::PdmChildArrayField<RimPolylineTarget*> m_targets;
caf::PdmField<cvf::Color3f> m_faultPlaneColor;
caf::PdmField<cvf::Color3f> m_modelPart1Color;
caf::PdmField<cvf::Color3f> m_modelPart2Color;
caf::PdmField<bool> m_showFaultPlane;
caf::PdmField<bool> m_showModelPlane;
caf::PdmField<double> m_extentVerticalAbove;
caf::PdmField<double> m_extentVerticalBelow;
caf::PdmField<double> m_extentHorizontal;
caf::PdmField<double> m_modelExtentFromAnchor;
caf::PdmField<double> m_modelMinZ;
caf::PdmField<double> m_modelBelowSize;
caf::PdmField<int> m_numberOfCellsHorzPart1;
caf::PdmField<int> m_numberOfCellsHorzPart2;
caf::PdmField<int> m_numberOfCellsVertUp;
caf::PdmField<int> m_numberOfCellsVertMid;
caf::PdmField<int> m_numberOfCellsVertLow;
cvf::ref<RigBasicPlane> m_faultPlane;
cvf::ref<RigFaultReactivationModel> m_modelPlane;
};

View File

@ -0,0 +1,186 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RimFaultReactivationModelCollection.h"
#include "RiaPreferencesGeoMech.h"
#include "RiuViewer.h"
#include "Rim3dView.h"
#include "RimFaultInView.h"
#include "RimFaultReactivationModel.h"
#include "RivFaultReactivationModelPartMgr.h"
#include "cvfBoundingBox.h"
#include "cvfModelBasicList.h"
#include "cafDisplayCoordTransform.h"
CAF_PDM_SOURCE_INIT( RimFaultReactivationModelCollection, "FaultReactivationModelCollection" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFaultReactivationModelCollection::RimFaultReactivationModelCollection()
{
CAF_PDM_InitObject( "Fault Reactivation Models", ":/fault_react_24x24.png" );
CAF_PDM_InitField( &m_userDescription, "UserDescription", QString( "Fault Reactivation Models" ), "Name" );
CAF_PDM_InitFieldNoDefault( &m_models, "FaultReactivationModels", "Models" );
m_models.uiCapability()->setUiTreeHidden( true );
setName( "Fault Reactivation Models" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFaultReactivationModelCollection::~RimFaultReactivationModelCollection()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFaultReactivationModel* RimFaultReactivationModelCollection::addNewModel( RimFaultInView* fault, cvf::Vec3d target1, cvf::Vec3d target2 )
{
auto newModel = new RimFaultReactivationModel();
newModel->setFault( fault );
newModel->setUserDescription( fault->name() );
newModel->setTargets( target1, target2 );
m_models.push_back( newModel );
newModel->updateVisualization();
// updateView();
return newModel;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimFaultReactivationModelCollection::empty()
{
return m_models.empty();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimFaultReactivationModelCollection::size()
{
return static_cast<int>( m_models.size() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFaultReactivationModelCollection::userDescription()
{
return m_userDescription;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModelCollection::setUserDescription( QString description )
{
m_userDescription = description;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimFaultReactivationModelCollection::userDescriptionField()
{
return &m_userDescription;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModelCollection::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
uiOrdering.skipRemainingFields( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModelCollection::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
if ( changedField == objectToggleField() )
{
updateView();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModelCollection::onChildDeleted( caf::PdmChildArrayFieldHandle* childArray,
std::vector<caf::PdmObjectHandle*>& referringObjects )
{
updateView();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModelCollection::updateView()
{
auto view = firstAncestorOrThisOfType<Rim3dView>();
if ( view ) view->scheduleCreateDisplayModelAndRedraw();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimFaultReactivationModelCollection::shouldBeVisibleInTree() const
{
return RiaPreferencesGeoMech::current()->validateFRMSettings();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModelCollection::appendPartsToModel( Rim3dView* view,
cvf::ModelBasicList* model,
caf::DisplayCoordTransform* transform,
const cvf::BoundingBox& boundingBox )
{
if ( !isChecked() ) return;
for ( auto& frm : m_models )
{
if ( frm->isChecked() )
{
frm->partMgr()->appendPolylinePartsToModel( view, model, transform, boundingBox );
frm->partMgr()->appendGeometryPartsToModel( model, transform, boundingBox );
frm->partMgr()->appendMeshPartsToModel( view, model, transform, boundingBox );
}
}
model->updateBoundingBoxesRecursive();
}

View File

@ -0,0 +1,81 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RimCheckableNamedObject.h"
#include "cafPdmChildArrayField.h"
#include "cafPdmField.h"
#include "cvfVector3.h"
#include <vector>
class RimFaultReactivationModel;
class RimFaultInView;
class Rim3dView;
namespace cvf
{
class ModelBasicList;
class Transform;
class BoundingBox;
} // namespace cvf
namespace caf
{
class DisplayCoordTransform;
}
class RimFaultReactivationModelCollection : public RimCheckableNamedObject
{
CAF_PDM_HEADER_INIT;
public:
RimFaultReactivationModelCollection();
~RimFaultReactivationModelCollection() override;
RimFaultReactivationModel* addNewModel( RimFaultInView* fault, cvf::Vec3d target1, cvf::Vec3d target2 );
bool empty();
int size();
bool shouldBeVisibleInTree() const;
QString userDescription();
void setUserDescription( QString description );
void appendPartsToModel( Rim3dView* view,
cvf::ModelBasicList* model,
caf::DisplayCoordTransform* transform,
const cvf::BoundingBox& boundingBox );
protected:
caf::PdmFieldHandle* userDescriptionField() override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void onChildDeleted( caf::PdmChildArrayFieldHandle* childArray, std::vector<caf::PdmObjectHandle*>& referringObjects ) override;
void updateView();
private:
caf::PdmField<QString> m_userDescription;
caf::PdmChildArrayField<RimFaultReactivationModel*> m_models;
};

View File

@ -56,6 +56,7 @@
#include "RimElementVectorResult.h"
#include "RimExtrudedCurveIntersection.h"
#include "RimFaultInViewCollection.h"
#include "RimFaultReactivationModelCollection.h"
#include "RimFlowCharacteristicsPlot.h"
#include "RimFlowDiagSolution.h"
#include "RimFracture.h"
@ -172,6 +173,10 @@ RimEclipseView::RimEclipseView()
m_faultCollection = new RimFaultInViewCollection;
m_faultCollection.uiCapability()->setUiTreeHidden( true );
CAF_PDM_InitFieldNoDefault( &m_faultReactivationModelCollection, "FaultReactivationModelCollection", "Fault Reactivation Models" );
m_faultReactivationModelCollection = new RimFaultReactivationModelCollection;
m_faultReactivationModelCollection.uiCapability()->setUiTreeHidden( true );
CAF_PDM_InitFieldNoDefault( &m_annotationCollection, "AnnotationCollection", "Annotations" );
m_annotationCollection = new RimAnnotationInViewCollection;
m_annotationCollection.uiCapability()->setUiTreeHidden( true );
@ -220,6 +225,9 @@ RimEclipseView::RimEclipseView()
setDeletable( true );
updateAnimations.connect( this, &RimEclipseView::onAnimationsUpdate );
m_faultReactVizModel = new cvf::ModelBasicList;
m_faultReactVizModel->setName( "FaultReactModel" );
}
//--------------------------------------------------------------------------------------------------
@ -306,6 +314,14 @@ RimFaultInViewCollection* RimEclipseView::faultCollection() const
return m_faultCollection;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFaultReactivationModelCollection* RimEclipseView::faultReactivationModelCollection() const
{
return m_faultReactivationModelCollection;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -598,6 +614,12 @@ void RimEclipseView::onCreateDisplayModel()
m_seismicSectionCollection->appendPartsToModel( this, m_seismicVizModel.p(), transform.p(), ownerCase()->allCellsBoundingBox() );
nativeOrOverrideViewer()->addStaticModelOnce( m_seismicVizModel.p(), isUsingOverrideViewer() );
// Fault reactivation models
m_faultReactVizModel->removeAllParts();
m_faultReactivationModelCollection->appendPartsToModel( this, m_faultReactVizModel.p(), transform.p(), ownerCase()->allCellsBoundingBox() );
nativeOrOverrideViewer()->addStaticModelOnce( m_faultReactVizModel.p(), isUsingOverrideViewer() );
// Surfaces
m_surfaceVizModel->removeAllParts();
if ( surfaceInViewCollection() )
@ -1879,25 +1901,21 @@ void RimEclipseView::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrderin
uiTreeOrdering.add( wellCollection() );
{
bool showFractureColors = false;
std::vector<RimFracture*> fractures = m_wellCollection->descendantsIncludingThisOfType<RimFracture>();
auto otherFractures = wellPathCollection()->descendantsIncludingThisOfType<RimFracture>();
fractures.insert( fractures.end(), otherFractures.begin(), otherFractures.end() );
if ( !fractures.empty() )
{
showFractureColors = true;
}
if ( showFractureColors )
{
uiTreeOrdering.add( fractureColors() );
}
}
uiTreeOrdering.add( faultCollection() );
if ( faultReactivationModelCollection()->shouldBeVisibleInTree() ) uiTreeOrdering.add( faultReactivationModelCollection() );
uiTreeOrdering.add( annotationCollection() );
uiTreeOrdering.add( intersectionCollection() );

View File

@ -68,6 +68,7 @@ class RimElementVectorResult;
class RimStreamlineInViewCollection;
class RimMultipleEclipseResults;
class RigEclipseResultAddress;
class RimFaultReactivationModelCollection;
namespace cvf
{
@ -91,15 +92,16 @@ public:
RiaDefines::View3dContent viewContent() const override;
RimEclipseCellColors* cellResult() const;
RimCellEdgeColors* cellEdgeResult() const;
RimElementVectorResult* elementVectorResult() const;
RimEclipseFaultColors* faultResultSettings() const;
RimStimPlanColors* fractureColors() const;
RimSimWellInViewCollection* wellCollection() const;
RimFaultInViewCollection* faultCollection() const;
RimVirtualPerforationResults* virtualPerforationResult() const;
RimStreamlineInViewCollection* streamlineCollection() const;
RimEclipseCellColors* cellResult() const;
RimCellEdgeColors* cellEdgeResult() const;
RimElementVectorResult* elementVectorResult() const;
RimEclipseFaultColors* faultResultSettings() const;
RimStimPlanColors* fractureColors() const;
RimSimWellInViewCollection* wellCollection() const;
RimFaultInViewCollection* faultCollection() const;
RimVirtualPerforationResults* virtualPerforationResult() const;
RimStreamlineInViewCollection* streamlineCollection() const;
RimFaultReactivationModelCollection* faultReactivationModelCollection() const;
bool showInvalidCells() const;
bool showInactiveCells() const;
@ -215,6 +217,9 @@ private:
void setVisibleGridParts( const std::vector<RivCellSetEnum>& cellSets );
void setVisibleGridPartsWatertight();
protected:
cvf::ref<cvf::ModelBasicList> m_faultReactVizModel;
private:
caf::PdmField<bool> m_showInvalidCells;
caf::PdmField<bool> m_showInactiveCells;
@ -228,9 +233,10 @@ private:
caf::PdmProxyValueField<std::vector<double>> m_cellResultData;
caf::PdmChildField<RimSimWellInViewCollection*> m_wellCollection;
caf::PdmChildField<RimFaultInViewCollection*> m_faultCollection;
caf::PdmChildField<RimStreamlineInViewCollection*> m_streamlineCollection;
caf::PdmChildField<RimSimWellInViewCollection*> m_wellCollection;
caf::PdmChildField<RimFaultInViewCollection*> m_faultCollection;
caf::PdmChildField<RimFaultReactivationModelCollection*> m_faultReactivationModelCollection;
caf::PdmChildField<RimStreamlineInViewCollection*> m_streamlineCollection;
caf::PdmChildField<RimEclipsePropertyFilterCollection*> m_propertyFilterCollection;
caf::PdmPointer<RimEclipsePropertyFilterCollection> m_overridePropertyFilterCollection;

View File

@ -29,6 +29,8 @@
#include "RimColorLegend.h"
#include "RimColorLegendCollection.h"
#include "RimEclipseCase.h"
#include "RimFaultInView.h"
#include "RimFaultInViewCollection.h"
#include "RimGeoMechCase.h"
#include "RimOilField.h"
#include "RimProject.h"
@ -581,3 +583,17 @@ void RimTools::optionItemsForSpecifiedWellPaths( const std::vector<RimWellPath*>
options->push_back( caf::PdmOptionItemInfo( wellPath->name(), wellPath, false, wellIcon ) );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTools::faultOptionItems( QList<caf::PdmOptionItemInfo>* options, RimFaultInViewCollection* coll )
{
if ( !options ) return;
if ( !coll ) return;
for ( auto& f : coll->faults() )
{
options->push_back( caf::PdmOptionItemInfo( f->name(), f, false, f->uiIconProvider() ) );
}
}

View File

@ -40,6 +40,7 @@ class RimWellPathCollection;
class RimCase;
class RimWellPath;
class RimSurfaceCollection;
class RimFaultInViewCollection;
//--------------------------------------------------------------------------------------------------
///
@ -69,6 +70,8 @@ public:
static void seismicDataOptionItems( QList<caf::PdmOptionItemInfo>* options, cvf::BoundingBox worldBBox, bool basicDataOnly = false );
static void seismicDataOptionItems( QList<caf::PdmOptionItemInfo>* options );
static void faultOptionItems( QList<caf::PdmOptionItemInfo>* options, RimFaultInViewCollection* coll );
static RimWellPathCollection* wellPathCollection();
static RimWellPath* firstWellPath();

View File

@ -89,6 +89,9 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RigTexturedSection.h
${CMAKE_CURRENT_LIST_DIR}/RigPressureDepthData.h
${CMAKE_CURRENT_LIST_DIR}/RigMswCenterLineCalculator.h
${CMAKE_CURRENT_LIST_DIR}/RigBasicPlane.h
${CMAKE_CURRENT_LIST_DIR}/RigGriddedPart3d.h
${CMAKE_CURRENT_LIST_DIR}/RigFaultReactivationModel.h
${CMAKE_CURRENT_LIST_DIR}/RigWellAllocationOverTime.h
${CMAKE_CURRENT_LIST_DIR}/RigWellResultBranch.h
${CMAKE_CURRENT_LIST_DIR}/RigWellResultFrame.h
@ -178,6 +181,9 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RigTexturedSection.cpp
${CMAKE_CURRENT_LIST_DIR}/RigPressureDepthData.cpp
${CMAKE_CURRENT_LIST_DIR}/RigMswCenterLineCalculator.cpp
${CMAKE_CURRENT_LIST_DIR}/RigBasicPlane.cpp
${CMAKE_CURRENT_LIST_DIR}/RigGriddedPart3d.cpp
${CMAKE_CURRENT_LIST_DIR}/RigFaultReactivationModel.cpp
${CMAKE_CURRENT_LIST_DIR}/RigWellAllocationOverTime.cpp
${CMAKE_CURRENT_LIST_DIR}/RigWellResultBranch.cpp
${CMAKE_CURRENT_LIST_DIR}/RigWellResultFrame.cpp

View File

@ -0,0 +1,167 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RigBasicPlane.h"
#include "cvfTextureImage.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigBasicPlane::RigBasicPlane()
: m_isRectValid( false )
, m_maxHorzExtent( 0.0 )
, m_maxVertExtentAbove( 0.0 )
, m_maxVertExtentBelow( 0.0 )
{
m_texture = new cvf::TextureImage();
m_texture->allocate( 1, 1 );
m_texture->fill( cvf::Color4ub( 0, 0, 0, 0 ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigBasicPlane::~RigBasicPlane()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigBasicPlane::reset()
{
m_isRectValid = false;
m_rect.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigBasicPlane::isValid() const
{
return m_isRectValid;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigBasicPlane::setPlane( cvf::Vec3d anchorPoint, cvf::Vec3d normal )
{
m_planeAnchor = anchorPoint;
m_planeNormal = normal;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigBasicPlane::setColor( cvf::Color3f color )
{
m_color = color;
m_texture->fill( cvf::Color4ub( color.rByte(), color.gByte(), color.bByte(), 255 ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigBasicPlane::setMaxExtentFromAnchor( double maxExtentHorz, double maxExtentVertAbove, double maxExtentVertBelow )
{
m_maxHorzExtent = maxExtentHorz;
m_maxVertExtentAbove = maxExtentVertAbove;
m_maxVertExtentBelow = maxExtentVertBelow;
}
//--------------------------------------------------------------------------------------------------
/// ti
/// 1 ----------- 2
/// | |
/// ml | | mr
/// | |
/// 0 ----------- 3
/// bi
//--------------------------------------------------------------------------------------------------
void RigBasicPlane::updateRect()
{
if ( ( m_maxHorzExtent <= 0.0 ) || ( m_maxVertExtentAbove <= 0.0 ) || ( m_maxVertExtentBelow <= 0.0 ) )
{
m_isRectValid = false;
return;
}
cvf::Vec3d zDirection( 0, 0, 1 );
auto alongPlane = m_planeNormal ^ zDirection;
auto upwards = m_planeNormal ^ alongPlane;
upwards.normalize();
alongPlane.normalize();
const double extHorz = m_maxHorzExtent / 2.0;
auto ml = m_planeAnchor + alongPlane * extHorz;
auto mr = m_planeAnchor - alongPlane * extHorz;
m_rect.resize( 4 );
m_rect[0] = ml - upwards * m_maxVertExtentAbove;
m_rect[1] = ml + upwards * m_maxVertExtentBelow;
m_rect[2] = mr + upwards * m_maxVertExtentBelow;
m_rect[3] = mr - upwards * m_maxVertExtentAbove;
m_isRectValid = true;
m_topIntersect = m_planeAnchor - upwards * m_maxVertExtentAbove;
m_bottomIntersect = m_planeAnchor + upwards * m_maxVertExtentBelow;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec3dArray RigBasicPlane::rect() const
{
return m_rect;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::TextureImage> RigBasicPlane::texture() const
{
return m_texture;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigBasicPlane::maxDepth()
{
if ( !m_isRectValid ) return 0.0;
double maxdepth = 0.0;
for ( auto p : m_rect )
{
maxdepth = std::max( maxdepth, std::abs( p.z() ) );
}
return maxdepth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<cvf::Vec3d, cvf::Vec3d> RigBasicPlane::intersectTopBottomLine()
{
return std::make_pair( m_topIntersect, m_bottomIntersect );
}

View File

@ -0,0 +1,75 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "cvfArray.h"
#include "cvfColor3.h"
#include "cvfObject.h"
#include "cvfPlane.h"
#include "cvfVector3.h"
#include <memory>
#include <vector>
namespace cvf
{
class TextureImage;
}
//==================================================================================================
///
///
//==================================================================================================
class RigBasicPlane : public cvf::Object
{
public:
RigBasicPlane();
~RigBasicPlane() override;
bool isValid() const;
void reset();
void updateRect();
void setPlane( cvf::Vec3d anchorPoint, cvf::Vec3d normal );
void setMaxExtentFromAnchor( double maxExtentHorz, double maxExtentVertAbove, double maxExtentVertBelow );
void setColor( cvf::Color3f color );
double maxDepth();
std::pair<cvf::Vec3d, cvf::Vec3d> intersectTopBottomLine();
cvf::Vec3dArray rect() const;
cvf::ref<cvf::TextureImage> texture() const;
private:
cvf::Vec3d m_planeNormal;
cvf::Vec3d m_planeAnchor;
double m_maxHorzExtent;
double m_maxVertExtentAbove;
double m_maxVertExtentBelow;
cvf::Vec3d m_topIntersect;
cvf::Vec3d m_bottomIntersect;
cvf::Vec3dArray m_rect;
bool m_isRectValid;
cvf::Color3f m_color;
cvf::ref<cvf::TextureImage> m_texture;
};

View File

@ -0,0 +1,308 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RigFaultReactivationModel.h"
#include "RigGriddedPart3d.h"
#include "RigPolyLinesData.h"
#include "cvfTextureImage.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFaultReactivationModel::RigFaultReactivationModel()
: m_maxZ( 0 )
, m_minZ( 0 )
, m_maxHorzExtent( 0 )
, m_isValid( false )
, m_cellCountHorzPart1( 1 )
, m_cellCountHorzPart2( 1 )
, m_cellCountVertUpper( 1 )
, m_cellCountVertMiddle( 1 )
, m_cellCountVertLower( 1 )
{
for ( auto part : allModelParts() )
{
m_parts[part] = RigFRModelPart();
m_parts[part].texture = new cvf::TextureImage();
m_parts[part].texture->allocate( 1, 1 );
m_parts[part].texture->fill( cvf::Color4ub( 0, 0, 0, 0 ) );
m_parts[part].rect.reserve( 4 );
}
m_cornerIndexes[ModelParts::HiPart1] = { 2, 3, 7, 6 };
m_cornerIndexes[ModelParts::MidPart1] = { 1, 2, 6, 5 };
m_cornerIndexes[ModelParts::LowPart1] = { 0, 1, 5, 4 };
m_cornerIndexes[ModelParts::HiPart2] = { 6, 7, 11, 10 };
m_cornerIndexes[ModelParts::MidPart2] = { 5, 6, 10, 9 };
m_cornerIndexes[ModelParts::LowPart2] = { 4, 5, 9, 8 };
for ( auto part : allGridParts() )
{
m_3dparts[part] = std::make_shared<RigGriddedPart3d>();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFaultReactivationModel::~RigFaultReactivationModel()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RigFaultReactivationModel::ModelParts> RigFaultReactivationModel::allModelParts() const
{
return { ModelParts::HiPart1, ModelParts::MidPart1, ModelParts::LowPart1, ModelParts::HiPart2, ModelParts::MidPart2, ModelParts::LowPart2 };
}
std::vector<RigFaultReactivationModel::GridPart> RigFaultReactivationModel::allGridParts() const
{
return { GridPart::PART1, GridPart::PART2 };
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFaultReactivationModel::reset()
{
m_isValid = false;
for ( auto part : allModelParts() )
{
m_parts[part].rect.clear();
m_parts[part].rect.reserve( 4 );
}
for ( auto part : allGridParts() )
{
m_3dparts[part]->reset();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFaultReactivationModel::isValid() const
{
return m_isValid;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFaultReactivationModel::setPlane( cvf::Vec3d anchorPoint, cvf::Vec3d normal )
{
m_planeAnchor = anchorPoint;
m_planeNormal = normal;
reset();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFaultReactivationModel::setPartColors( cvf::Color3f part1Color, cvf::Color3f part2Color )
{
for ( auto part : { ModelParts::HiPart1, ModelParts::MidPart1, ModelParts::LowPart1 } )
{
m_parts[part].texture->fill( cvf::Color4ub( part1Color.rByte(), part1Color.gByte(), part1Color.bByte(), 255 ) );
}
for ( auto part : { ModelParts::HiPart2, ModelParts::MidPart2, ModelParts::LowPart2 } )
{
m_parts[part].texture->fill( cvf::Color4ub( part2Color.rByte(), part2Color.gByte(), part2Color.bByte(), 255 ) );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFaultReactivationModel::setMaxExtentFromAnchor( double maxExtentHorz, double minZ, double maxZ )
{
m_maxHorzExtent = maxExtentHorz;
m_minZ = minZ;
m_maxZ = maxZ;
reset();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFaultReactivationModel::setFaultPlaneIntersect( cvf::Vec3d faultPlaneTop, cvf::Vec3d faultPlaneBottom )
{
m_faultPlaneIntersectBottom = faultPlaneBottom;
m_faultPlaneIntersectTop = faultPlaneTop;
reset();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFaultReactivationModel::setCellCounts( int horzPart1, int horzPart2, int vertUpper, int vertMiddle, int vertLower )
{
m_cellCountHorzPart1 = horzPart1;
m_cellCountHorzPart2 = horzPart2;
m_cellCountVertUpper = vertUpper;
m_cellCountVertMiddle = vertMiddle;
m_cellCountVertLower = vertLower;
reset();
}
//--------------------------------------------------------------------------------------------------
/// 7
/// 3----------|----------- 11
/// | | |
/// | | |
/// | | |
/// 2|---------|----------| 10
/// | \6 |
/// | X Anchor |
/// | \ |
/// 1-------------|------- 9
/// | 5| |
/// | | |
/// | | |
/// | | |
/// 0-------------|-------- 8
/// 4
///
///
///
//--------------------------------------------------------------------------------------------------
void RigFaultReactivationModel::updateRects()
{
reset();
if ( ( m_maxHorzExtent <= 0.0 ) || ( m_minZ == m_maxZ ) )
{
return;
}
cvf::Vec3d zDir( 0, 0, 1 );
auto alongPlane = m_planeNormal ^ zDir;
alongPlane.normalize();
// how far from anchor point we should stop
const double extHorz = m_maxHorzExtent / 2.0;
auto mr = m_planeAnchor + alongPlane * extHorz;
auto ml = m_planeAnchor - alongPlane * extHorz;
cvf::Vec3dArray points;
points.resize( 12 );
points[0] = ml;
points[0].z() = -m_maxZ;
points[1] = ml;
points[1].z() = m_faultPlaneIntersectBottom.z();
points[2] = ml;
points[2].z() = m_faultPlaneIntersectTop.z();
points[3] = ml;
points[3].z() = -m_minZ;
points[4] = m_faultPlaneIntersectBottom;
points[4].z() = -m_maxZ;
points[5] = m_faultPlaneIntersectBottom;
points[6] = m_faultPlaneIntersectTop;
points[7] = m_faultPlaneIntersectTop;
points[7].z() = -m_minZ;
points[8] = mr;
points[8].z() = -m_maxZ;
points[9] = mr;
points[9].z() = m_faultPlaneIntersectBottom.z();
points[10] = mr;
points[10].z() = m_faultPlaneIntersectTop.z();
points[11] = mr;
points[11].z() = -m_minZ;
for ( auto part : allModelParts() )
{
for ( auto i : m_cornerIndexes[part] )
{
m_parts[part].rect.push_back( points[i] );
}
}
m_isValid = true;
generateGrids( points );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> RigFaultReactivationModel::rect( ModelParts part ) const
{
return m_parts.at( part ).rect;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::TextureImage> RigFaultReactivationModel::texture( ModelParts part ) const
{
return m_parts.at( part ).texture;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<std::vector<cvf::Vec3d>>& RigFaultReactivationModel::meshLines( GridPart part ) const
{
return m_3dparts.at( part )->meshLines();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFaultReactivationModel::generateGrids( cvf::Vec3dArray points )
{
m_3dparts[GridPart::PART1]->generateGeometry( { points[0], points[1], points[2], points[3], points[4], points[5], points[6], points[7] },
m_cellCountHorzPart1,
m_cellCountVertLower,
m_cellCountVertMiddle,
m_cellCountVertUpper );
m_3dparts[GridPart::PART2]->generateGeometry( { points[8], points[9], points[10], points[11], points[4], points[5], points[6], points[7] },
m_cellCountHorzPart2,
m_cellCountVertLower,
m_cellCountVertMiddle,
m_cellCountVertUpper );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::shared_ptr<RigGriddedPart3d> RigFaultReactivationModel::grid( GridPart part ) const
{
return m_3dparts.at( part );
}

View File

@ -0,0 +1,124 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "cvfArray.h"
#include "cvfColor3.h"
#include "cvfObject.h"
#include "cvfPlane.h"
#include "cvfVector3.h"
#include <map>
#include <memory>
#include <vector>
namespace cvf
{
class TextureImage;
}
class RigGriddedPart3d;
class RigFRModelPart
{
public:
RigFRModelPart(){};
~RigFRModelPart(){};
std::vector<cvf::Vec3d> rect;
cvf::ref<cvf::TextureImage> texture;
};
//==================================================================================================
///
///
//==================================================================================================
class RigFaultReactivationModel : public cvf::Object
{
public:
enum class ModelParts
{
HiPart1 = 0,
MidPart1,
LowPart1,
HiPart2,
MidPart2,
LowPart2
};
enum class GridPart
{
PART1,
PART2
};
public:
RigFaultReactivationModel();
~RigFaultReactivationModel() override;
std::vector<ModelParts> allModelParts() const;
std::vector<GridPart> allGridParts() const;
bool isValid() const;
void reset();
void setPlane( cvf::Vec3d anchorPoint, cvf::Vec3d normal );
void setFaultPlaneIntersect( cvf::Vec3d faultPlaneTop, cvf::Vec3d faultPlaneBottom );
void setMaxExtentFromAnchor( double maxExtentHorz, double minZ, double maxZ );
void setCellCounts( int horzPart1, int horzPart2, int vertUpper, int vertMiddle, int vertLower );
void updateRects();
void setPartColors( cvf::Color3f part1Color, cvf::Color3f part2Color );
std::vector<cvf::Vec3d> rect( ModelParts part ) const;
cvf::ref<cvf::TextureImage> texture( ModelParts part ) const;
const std::vector<std::vector<cvf::Vec3d>>& meshLines( GridPart part ) const;
std::shared_ptr<RigGriddedPart3d> grid( GridPart part ) const;
protected:
void generateGrids( cvf::Vec3dArray points );
private:
cvf::Vec3d m_planeNormal;
cvf::Vec3d m_planeAnchor;
cvf::Vec3d m_faultPlaneIntersectTop;
cvf::Vec3d m_faultPlaneIntersectBottom;
double m_maxHorzExtent;
double m_minZ;
double m_maxZ;
int m_cellCountHorzPart1;
int m_cellCountHorzPart2;
int m_cellCountVertUpper;
int m_cellCountVertMiddle;
int m_cellCountVertLower;
std::map<ModelParts, std::vector<int>> m_cornerIndexes;
std::map<ModelParts, RigFRModelPart> m_parts;
bool m_isValid;
std::map<GridPart, std::shared_ptr<RigGriddedPart3d>> m_3dparts;
};

View File

@ -0,0 +1,275 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RigGriddedPart3d.h"
#include "cvfTextureImage.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigGriddedPart3d::RigGriddedPart3d()
: m_thickness( 10.0 )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigGriddedPart3d::~RigGriddedPart3d()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigGriddedPart3d::reset()
{
m_borderSurfaceElements.clear();
m_vertices.clear();
m_elementIndices.clear();
m_meshLines.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec3d RigGriddedPart3d::stepVector( cvf::Vec3d start, cvf::Vec3d stop, int nSteps )
{
cvf::Vec3d vec = stop - start;
return vec.getNormalized() * ( vec.length() / nSteps );
}
//--------------------------------------------------------------------------------------------------
/// Point index in input
///
///
/// 3 ----------- 7 *
/// | | *
/// | | *
/// | | *
/// 2 |---------| 6 *
/// | \ *
/// | \ *
/// | \ *
/// 1 -------------| 5 *
/// | | *
/// | | *
/// | | *
/// | | *
/// 0 -------------- 4 *
///
/// Assumes 0->4, 1->5, 2->6 and 3->7 is parallel
///
///
//--------------------------------------------------------------------------------------------------
void RigGriddedPart3d::generateGeometry( std::vector<cvf::Vec3d> inputPoints, int nHorzCells, int nVertCellsLower, int nVertCellsMiddle, int nVertCellsUpper )
{
reset();
cvf::Vec3d step0to1 = stepVector( inputPoints[0], inputPoints[1], nVertCellsLower );
cvf::Vec3d step1to2 = stepVector( inputPoints[1], inputPoints[2], nVertCellsMiddle );
cvf::Vec3d step2to3 = stepVector( inputPoints[2], inputPoints[3], nVertCellsUpper );
cvf::Vec3d step4to5 = stepVector( inputPoints[4], inputPoints[5], nVertCellsLower );
cvf::Vec3d step5to6 = stepVector( inputPoints[5], inputPoints[6], nVertCellsMiddle );
cvf::Vec3d step6to7 = stepVector( inputPoints[6], inputPoints[7], nVertCellsUpper );
cvf::Vec3d step0to4 = stepVector( inputPoints[0], inputPoints[4], nHorzCells );
cvf::Vec3d tVec = step0to4 ^ step0to1;
tVec.normalize();
tVec *= m_thickness;
const std::vector<double> m_thicknessFactors = { -1.0, 0.0, 1.0 };
const int nThicknessCells = 2;
const int nVertCells = nVertCellsLower + nVertCellsMiddle + nVertCellsUpper;
const std::vector<int> vertCells = { nVertCellsLower, nVertCellsMiddle, nVertCellsUpper + 1 };
const std::vector<cvf::Vec3d> firstSteps = { step0to1, step1to2, step2to3 };
const std::vector<cvf::Vec3d> lastSteps = { step4to5, step5to6, step6to7 };
// ** generate vertices
m_vertices.reserve( (size_t)( ( nVertCells + 1 ) * ( nHorzCells + 1 ) ) );
cvf::Vec3d p = inputPoints[0];
cvf::Vec3d pLast = inputPoints[4];
for ( int i = 0; i < (int)vertCells.size(); i++ )
{
for ( int v = 0; v < vertCells[i]; v++ )
{
cvf::Vec3d stepHorz = stepVector( p, pLast, nHorzCells );
cvf::Vec3d p2 = p;
for ( int h = 0; h <= nHorzCells; h++ )
{
for ( int t = 0; t < (int)m_thicknessFactors.size(); t++ )
{
m_vertices.push_back( p2 + m_thicknessFactors[t] * tVec );
}
p2 += stepHorz;
pLast = p2;
}
p += firstSteps[i];
pLast += lastSteps[i];
}
}
// ** generate elements of type hex8
m_elementIndices.resize( (size_t)( nVertCells * nHorzCells * nThicknessCells ) );
m_borderSurfaceElements[BorderSurface::UpperSurface] = {};
m_borderSurfaceElements[BorderSurface::FaultSurface] = {};
m_borderSurfaceElements[BorderSurface::LowerSurface] = {};
int layerIndex = 0;
int elementIdx = 0;
BorderSurface currentRegion = BorderSurface::LowerSurface;
const int nextLayerIdxOff = ( nHorzCells + 1 ) * ( nThicknessCells + 1 );
const int nThicknessOff = nThicknessCells + 1;
for ( int v = 0; v < nVertCells; v++ )
{
if ( v >= nVertCellsLower ) currentRegion = BorderSurface::FaultSurface;
if ( v >= nVertCellsLower + nVertCellsMiddle ) currentRegion = BorderSurface::UpperSurface;
int i = layerIndex;
for ( int h = 0; h < nHorzCells; h++ )
{
for ( int t = 0; t < nThicknessCells; t++ )
{
m_elementIndices[elementIdx].push_back( t + i );
m_elementIndices[elementIdx].push_back( t + i + nThicknessOff );
m_elementIndices[elementIdx].push_back( t + i + nThicknessOff + 1 );
m_elementIndices[elementIdx].push_back( t + i + 1 );
m_elementIndices[elementIdx].push_back( t + nextLayerIdxOff + i );
m_elementIndices[elementIdx].push_back( t + nextLayerIdxOff + i + nThicknessOff );
m_elementIndices[elementIdx].push_back( t + nextLayerIdxOff + i + nThicknessOff + 1 );
m_elementIndices[elementIdx].push_back( t + nextLayerIdxOff + i + 1 );
elementIdx++;
}
i += nThicknessOff;
}
// add elements to border surface in current region
m_borderSurfaceElements[currentRegion].push_back( elementIdx - 2 );
m_borderSurfaceElements[currentRegion].push_back( elementIdx - 1 );
layerIndex += nextLayerIdxOff;
}
// generate meshlines for 2d viz
generateMeshlines( { inputPoints[0], inputPoints[1], inputPoints[5], inputPoints[4] }, nHorzCells, nVertCellsLower );
generateMeshlines( { inputPoints[1], inputPoints[2], inputPoints[6], inputPoints[5] }, nHorzCells, nVertCellsMiddle );
generateMeshlines( { inputPoints[2], inputPoints[3], inputPoints[7], inputPoints[6] }, nHorzCells, nVertCellsUpper );
}
//--------------------------------------------------------------------------------------------------
/// Point index in input
///
/// 1 ____________ 2
/// | /
/// | /
/// | /
/// | /
/// |_______/
/// 0 3
///
/// Assumes 0->3 and 1->2 is parallel
//--------------------------------------------------------------------------------------------------
void RigGriddedPart3d::generateMeshlines( std::vector<cvf::Vec3d> cornerPoints, int numHorzCells, int numVertCells )
{
cvf::Vec3d step0to1 = stepVector( cornerPoints[0], cornerPoints[1], numVertCells );
cvf::Vec3d step0to3 = stepVector( cornerPoints[0], cornerPoints[3], numHorzCells );
cvf::Vec3d step1to2 = stepVector( cornerPoints[1], cornerPoints[2], numHorzCells );
cvf::Vec3d step3to2 = stepVector( cornerPoints[3], cornerPoints[2], numVertCells );
// horizontal lines
cvf::Vec3d startP = cornerPoints[0];
cvf::Vec3d endP = cornerPoints[3];
for ( int v = 0; v <= numVertCells; v++ )
{
m_meshLines.push_back( { startP, endP } );
startP += step0to1;
endP += step3to2;
}
// vertical lines
startP = cornerPoints[0];
endP = cornerPoints[1];
for ( int h = 0; h <= numHorzCells; h++ )
{
m_meshLines.push_back( { startP, endP } );
startP += step0to3;
endP += step1to2;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<cvf::Vec3d>& RigGriddedPart3d::vertices() const
{
return m_vertices;
}
//--------------------------------------------------------------------------------------------------
/// Output elements will be of type HEX8
///
/// 7---------6
/// /| /|
/// / | / |
/// 4---------5 | z
/// | 3------|--2 | y
/// | / | / | /
/// |/ |/ |/
/// 0---------1 ----- x
///
//--------------------------------------------------------------------------------------------------
const std::vector<std::vector<unsigned int>>& RigGriddedPart3d::elementIndices() const
{
return m_elementIndices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::map<RigGriddedPart3d::BorderSurface, std::vector<unsigned int>>& RigGriddedPart3d::borderSurfaceElements() const
{
return m_borderSurfaceElements;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<std::vector<cvf::Vec3d>>& RigGriddedPart3d::meshLines() const
{
return m_meshLines;
}

View File

@ -0,0 +1,65 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "cvfObject.h"
#include "cvfVector3.h"
#include <map>
#include <vector>
//==================================================================================================
///
///
//==================================================================================================
class RigGriddedPart3d : public cvf::Object
{
public:
enum class BorderSurface
{
UpperSurface = 0,
FaultSurface,
LowerSurface
};
public:
RigGriddedPart3d();
~RigGriddedPart3d() override;
void reset();
void generateGeometry( std::vector<cvf::Vec3d> inputPoints, int nHorzCells, int nVertCellsLower, int nVertCellsMiddle, int nVertCellsUpper );
const std::vector<cvf::Vec3d>& vertices() const;
const std::vector<std::vector<unsigned int>>& elementIndices() const;
const std::map<BorderSurface, std::vector<unsigned int>>& borderSurfaceElements() const;
const std::vector<std::vector<cvf::Vec3d>>& meshLines() const;
protected:
cvf::Vec3d stepVector( cvf::Vec3d start, cvf::Vec3d stop, int nSteps );
void generateMeshlines( std::vector<cvf::Vec3d> cornerPoints, int numHorzCells, int numVertCells );
private:
std::vector<cvf::Vec3d> m_vertices;
std::vector<std::vector<unsigned int>> m_elementIndices;
std::map<BorderSurface, std::vector<unsigned int>> m_borderSurfaceElements;
std::vector<std::vector<cvf::Vec3d>> m_meshLines;
double m_thickness;
};

View File

@ -437,17 +437,21 @@ void RiuViewerCommands::displayContextMenu( QMouseEvent* event )
menuBuilder.addSeparator();
QString faultName = fault->name();
QVariantList hideFaultList;
QVariantList faultDataList;
qulonglong currentCellIndex = m_currentCellIndex;
hideFaultList.push_back( currentCellIndex );
hideFaultList.push_back( m_currentFaceIndex );
faultDataList.push_back( currentCellIndex );
faultDataList.push_back( m_currentFaceIndex );
menuBuilder.addCmdFeatureWithUserData( "RicEclipseHideFaultFeature", QString( "Hide " ) + faultName, hideFaultList );
menuBuilder.addCmdFeatureWithUserData( "RicEclipseHideFaultFeature", QString( "Hide " ) + faultName, faultDataList );
menuBuilder.addCmdFeatureWithUserData( "RicEclipseShowOnlyFaultFeature",
QString( "Show " ) + faultName + QString( " - Others Off" ),
QVariant( fault->name() ) );
menuBuilder.addCmdFeatureWithUserData( "RicNewFaultReactModelingFeature",
QString( "New Fault Re-activation Model" ),
faultDataList );
menuBuilder.addSeparator();
}
}