Initial GetGridSurface with IJK-filter

This commit is contained in:
Jørgen Herje 2024-02-22 14:10:31 +01:00
parent 9eec4e6d4b
commit 76f2607190
11 changed files with 342 additions and 64 deletions

View File

@ -203,6 +203,33 @@ void RivGridPartMgr::appendPartsToModel( cvf::ModelBasicList* model )
if ( m_surfaceGridLines.notNull() ) model->addPart( m_surfaceGridLines.p() );
}
//--------------------------------------------------------------------------------------------------
/// Returns the surface vertices of the grid part
///
/// Creates vertices if they do not exist
/// Used for gRPC service GridGeometryExtraction
//--------------------------------------------------------------------------------------------------
cvf::Vec3fArray* RivGridPartMgr::getOrCreateSurfaceVertices()
{
return m_surfaceGenerator.getOrCreateVertices();
}
//--------------------------------------------------------------------------------------------------
/// Get map from quad index to cell index
///
/// Used for gRPC service GridGeometryExtraction
//--------------------------------------------------------------------------------------------------
std::vector<size_t> RivGridPartMgr::getSurfaceQuadToCellIndicesArray()
{
auto* gridQuadToCellFaceMapper = m_surfaceGenerator.quadToCellFaceMapper();
if ( gridQuadToCellFaceMapper == nullptr )
{
return std::vector<size_t>();
}
return gridQuadToCellFaceMapper->quadToCellIndicesArray();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -30,6 +30,8 @@
#include "cvfStructGridGeometryGenerator.h"
#include <vector>
namespace cvf
{
class StructGridInterface;
@ -69,6 +71,9 @@ public:
void appendPartsToModel( cvf::ModelBasicList* model );
cvf::Vec3fArray* getOrCreateSurfaceVertices();
std::vector<size_t> getSurfaceQuadToCellIndicesArray();
private:
void generatePartGeometry( cvf::StructGridGeometryGenerator& geoBuilder );

View File

@ -179,6 +179,22 @@ void RivReservoirPartMgr::appendElementVectorResultPartsToModel( cvf::ModelBasic
}
}
//--------------------------------------------------------------------------------------------------
/// Get the part manager for main grid
///
/// Needed for the gRPC service for GridGeometryExtraction
//--------------------------------------------------------------------------------------------------
RivGridPartMgr* RivReservoirPartMgr::mainGridPartManager()
{
if ( m_allGrids.empty() )
{
return nullptr;
}
// First grid should be the main grid
return m_allGrids.at( 0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -76,6 +76,8 @@ public:
// Element Vector Result
void appendElementVectorResultPartsToModel( cvf::ModelBasicList* model, size_t timeStepIndex );
RivGridPartMgr* mainGridPartManager();
private:
cvf::Collection<RivGridPartMgr> m_allGrids; // Main grid and all LGR's
cvf::ref<RivElementVectorResultPartMgr> m_elementVectorResultMgr;

View File

@ -910,6 +910,14 @@ void RivReservoirViewPartMgr::computePropertyVisibility( cvf::UByteArray*
}
}
//--------------------------------------------------------------------------------------------------
/// Needed for the gRPC service for GridGeometryExtraction
//--------------------------------------------------------------------------------------------------
RivReservoirPartMgr* RivReservoirViewPartMgr::rangeFilteredReservoirPartManager( size_t timeStepIndex )
{
return reservoirPartManager( RivCellSetEnum::RANGE_FILTERED, timeStepIndex );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -97,6 +97,8 @@ public:
const cvf::UByteArray* rangeFilterVisibility,
RimEclipsePropertyFilterCollection* propFilterColl );
RivReservoirPartMgr* rangeFilteredReservoirPartManager( size_t timeStepIndex );
private:
void createGeometry( RivCellSetEnum geometryType );
void computeVisibility( cvf::UByteArray* cellVisibility, RivCellSetEnum geometryType, RigGridBase* grid, size_t gridIdx );

View File

@ -212,9 +212,12 @@ ref<DrawableGeo> StructGridGeometryGenerator::generateSurface()
}
//--------------------------------------------------------------------------------------------------
/// Get the vertices of the generated surface, if the vertices have not been generated yet,
/// they will be generated.
///
/// Needed for the gRPC service for GridGeometryExtraction
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Vec3fArray> StructGridGeometryGenerator::getOrCreateVertices()
Vec3fArray* StructGridGeometryGenerator::getOrCreateVertices()
{
if ( m_vertices.isNull() || m_vertices->size() == 0 )
{
@ -223,7 +226,7 @@ cvf::ref<cvf::Vec3fArray> StructGridGeometryGenerator::getOrCreateVertices()
CVF_ASSERT( m_vertices.notNull() );
return m_vertices;
return m_vertices.p();
}
//--------------------------------------------------------------------------------------------------

View File

@ -137,6 +137,8 @@ public:
std::vector<size_t>& quadToCellIndexMap() { return m_quadsToCells; }
std::vector<StructGridInterface::FaceType>& quadToCellFaceMap() { return m_quadsToFace; }
const std::vector<size_t> quadToCellIndicesArray() const { return m_quadsToCells; }
private:
std::vector<size_t> m_quadsToCells;
std::vector<StructGridInterface::FaceType> m_quadsToFace;
@ -195,7 +197,7 @@ public:
ref<DrawableGeo> createMeshDrawable();
ref<DrawableGeo> createOutlineMeshDrawable( double creaseAngle );
cvf::ref<cvf::Vec3fArray> getOrCreateVertices();
Vec3fArray* getOrCreateVertices();
static ref<DrawableGeo> createMeshDrawableFromSingleCell( const StructGridInterface* grid, size_t cellIndex );

View File

@ -14,12 +14,18 @@ from rips.generated.GridGeometryExtraction_pb2 import *
rips_instance = Instance.find()
grid_geometry_extraction_stub = GridGeometryExtractionStub(rips_instance.channel)
get_grid_surface_request = GridGeometryExtraction__pb2.GetGridSurfaceRequest(gridFilename=None, ijkIndexFilter=None,cellIndexFilter=None,propertyFilter=None)
grid_file_name = None
ijk_index_filter = GridGeometryExtraction__pb2.IJKIndexFilter(iMin=0, iMax =1, jMin=2, jMax=3, kMin=0, kMax=3)
get_grid_surface_request = GridGeometryExtraction__pb2.GetGridSurfaceRequest(gridFilename=grid_file_name, ijkIndexFilter=ijk_index_filter,cellIndexFilter=None,propertyFilter=None)
get_grid_surface_response: GridGeometryExtraction__pb2.GetGridSurfaceResponse = grid_geometry_extraction_stub.GetGridSurface(get_grid_surface_request)
get_grid_surface_response.gridDimensions
vertex_array = get_grid_surface_response.vertexArray
quad_indices_array = get_grid_surface_response.quadIndicesArr
origin_utm = get_grid_surface_response.originUtm
source_cell_indices_arr = get_grid_surface_response.sourceCellIndicesArr
grid_dimensions = get_grid_surface_response.gridDimensions
num_vertex_coords = 3 # [x, y, z]
num_vertices_per_quad = 4 # [v1, v2, v3, v4]
@ -59,6 +65,10 @@ fig = go.Figure(data=[go.Mesh3d(
colorscale=[[0, 'gold'],[0.5, 'mediumturquoise'],[1.0, 'magenta']]
)])
print(f"Number of quads: {num_quads}")
print(f"Source cell indices array length: {len(source_cell_indices_arr)}")
print(f"Origin UTM coordinates [x, y, z]: [{origin_utm.x}, {origin_utm.y}, {origin_utm.z}]")
print(f"Grid dimensions [I, J, K]: [{grid_dimensions.dimensions.i}, {grid_dimensions.dimensions.j}, {grid_dimensions.dimensions.k}]")
print(fig.data)
fig.show()

View File

@ -1,13 +1,14 @@
#include "RiaGrpcGridGeometryExtractionService.h"
// #include "VectorDefines.pb.h"
#include "qstring.h"
#include "cvfStructGridGeometryGenerator.h"
#include "Commands/RicImportGeneralDataFeature.h"
#include "RiaApplication.h"
#include "RiaGrpcCallbacks.h"
#include "RiaGrpcHelper.h"
#include "RifReaderSettings.h"
#include "RigEclipseCaseData.h"
#include "RigFemPartCollection.h"
#include "RigFemPartGrid.h"
@ -15,13 +16,25 @@
#include "RigGridBase.h"
#include "RigMainGrid.h"
#include "RimCase.h"
#include "RimCellFilterCollection.h"
#include "RimCellRangeFilter.h"
#include "RimEclipseCase.h"
#include "RimEclipseView.h"
#include "RimGeoMechCase.h"
#include "RimGridView.h"
#include "RimProject.h"
#include "RivGridPartMgr.h"
#include "RivReservoirPartMgr.h"
#include "RivReservoirViewPartMgr.h"
#include "cafSelectionManagerTools.h"
#include "cvfArray.h"
#include "cvfDrawableGeo.h"
#include "cvfStructGridGeometryGenerator.h"
#include "qfileinfo.h"
#include "qstring.h"
//--------------------------------------------------------------------------------------------------
///
@ -30,77 +43,84 @@ grpc::Status RiaGrpcGridGeometryExtractionService::GetGridSurface( grpc::ServerC
const rips::GetGridSurfaceRequest* request,
rips::GetGridSurfaceResponse* response )
{
// Get resinsight instance and open grid
RiaApplication* applicationInstance = RiaApplication::instance();
// Reset all pointers
resetInternalPointers();
if ( applicationInstance == nullptr )
// Initialize pointer
auto firstStatus = initializeApplicationAndEclipseCaseAndEclipseViewFromAbsoluteFilePath( request->gridfilename() );
if ( firstStatus.error_code() != grpc::StatusCode::OK )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND, "ResInsight instance not found" );
return firstStatus;
}
applicationInstance->createMockModel();
RimProject* project = applicationInstance->project();
if ( project == nullptr )
// Apply ijk-filtering - assuming 0-indexing from gRPC
auto secondStatus = applyIJKCellFilterToEclipseCase( request->ijkindexfilter() );
if ( secondStatus.error_code() != grpc::StatusCode::OK )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No project found" );
return secondStatus;
}
// 1)
// Retrieve grid surface vertices from eclipse view
auto thirdStatus = initializeMainGridPartManagerFromEclipseView();
if ( thirdStatus.error_code() != grpc::StatusCode::OK )
{
// 1. RimEclipseView
// 2. RivReservoirViewPartMgr using reservoirGridPartManager()
// 3. reservoirPartManager(RivCellSetEnum::RANGE_FILTERED, timeStepIndex); , timeStepIndex = 0 (make method
// public?)
// 4. ... ?
return thirdStatus;
}
// 2)
auto* gridSurfaceVertices = m_mainGridPartManager->getOrCreateSurfaceVertices();
if ( gridSurfaceVertices == nullptr )
{
// Temporary code using mainGrid
auto eclipseCases = project->eclipseCases();
if ( eclipseCases.empty() )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No grid cases found" );
}
auto* eclipseCase = eclipseCases.front();
auto* mainGrid = eclipseCase->eclipseCaseData()->mainGrid();
// Get RigFemPartGrid object ?
cvf::StructGridGeometryGenerator gridGeometryGenerator( mainGrid, false );
cvf::UByteArray* cellVisibilities = new cvf::UByteArray( mainGrid->cellCount() );
cellVisibilities->setAll( 1 );
auto* faceVisibilityFilter = new RigGridCellFaceVisibilityFilter( mainGrid );
gridGeometryGenerator.setCellVisibility( cellVisibilities );
gridGeometryGenerator.addFaceVisibilityFilter( faceVisibilityFilter );
auto gridSurfaceVertices = gridGeometryGenerator.getOrCreateVertices();
if ( gridSurfaceVertices.p() == nullptr )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No grid vertices found" );
}
// Set vertex_array and quadindicesarr response
const auto* verticesArray = gridSurfaceVertices.p();
for ( int i = 0; i < verticesArray->size(); ++i )
{
const auto& vertex = verticesArray->get( i );
response->add_vertexarray( vertex.x() );
response->add_vertexarray( vertex.y() );
response->add_vertexarray( vertex.z() );
response->add_quadindicesarr( i );
}
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No grid vertices found" );
}
// TODO: Add:
// - sourceCellIndicesArr
// - gridDimensions
// - originUtm
// Set vertex_array and quadindicesarr response
for ( int i = 0; i < gridSurfaceVertices->size(); ++i )
{
const auto& vertex = gridSurfaceVertices->get( i );
response->add_vertexarray( vertex.x() );
response->add_vertexarray( vertex.y() );
response->add_vertexarray( vertex.z() );
applicationInstance->closeProject();
response->add_quadindicesarr( i );
}
// Origin in utm is the offset
rips::Vec3d* modelOffset = new rips::Vec3d;
const auto mainGridModelOffset = m_eclipseView->mainGrid()->displayModelOffset();
modelOffset->set_x( mainGridModelOffset.x() );
modelOffset->set_y( mainGridModelOffset.y() );
modelOffset->set_z( mainGridModelOffset.z() );
response->set_allocated_originutm( modelOffset );
// Source cell indices from main grid part manager
const auto sourceCellIndicesArray = m_mainGridPartManager->getSurfaceQuadToCellIndicesArray();
if ( sourceCellIndicesArray.empty() )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No source cell indices array found" );
}
for ( const auto& sourceCellIndex : sourceCellIndicesArray )
{
response->add_sourcecellindicesarr( static_cast<google::protobuf::uint32>( sourceCellIndex ) );
}
// Set grid dimensions
const auto countI = m_eclipseView->mainGrid()->cellCountI();
const auto countJ = m_eclipseView->mainGrid()->cellCountJ();
const auto countK = m_eclipseView->mainGrid()->cellCountK();
rips::Vec3i* dimensions = new rips::Vec3i;
rips::GridDimensions* gridDimensions = new rips::GridDimensions;
dimensions->set_i( countI );
dimensions->set_j( countJ );
dimensions->set_k( countK );
gridDimensions->set_allocated_dimensions( dimensions );
response->set_allocated_griddimensions( gridDimensions );
// Close project and return
if ( m_application != nullptr )
{
m_application->closeProject();
}
resetInternalPointers();
return grpc::Status::OK;
}
@ -130,6 +150,170 @@ std::vector<RiaGrpcCallbackInterface*> RiaGrpcGridGeometryExtractionService::cre
&Self::RequestCutAlongPolyline ) };
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaGrpcGridGeometryExtractionService::resetInternalPointers()
{
m_application = nullptr;
m_eclipseCase = nullptr;
m_eclipseView = nullptr;
m_mainGridPartManager = nullptr;
}
//--------------------------------------------------------------------------------------------------
/// Apply ijk-filtering - assuming 0-indexing from gRPC
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcGridGeometryExtractionService::applyIJKCellFilterToEclipseCase( const rips::IJKIndexFilter& filter )
{
if ( m_eclipseCase == nullptr )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No initialized eclipse case found" );
}
if ( m_eclipseView == nullptr )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No initialized eclipse view found" );
}
// Find the selected Cell Filter Collection
RimCellFilterCollection* filtColl = m_eclipseView->cellFilterCollection();
if ( filtColl == nullptr )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No cell filter collection found for eclipse view" );
}
// Add range filter object
const int sliceDirection = -1;
const int gridIndex = 0;
RimCellRangeFilter* cellRangeFilter = filtColl->addNewCellRangeFilter( m_eclipseCase, gridIndex, sliceDirection );
// Apply ijk-filter values to range filter object
cellRangeFilter->startIndexI = filter.imin() + 1; // Eclipse indexing, first index is 1
cellRangeFilter->startIndexJ = filter.jmin() + 1; // Eclipse indexing, first index is 1
cellRangeFilter->startIndexK = filter.kmin() + 1; // Eclipse indexing, first index is 1
cellRangeFilter->cellCountI = filter.imax() - filter.imin() + 1;
cellRangeFilter->cellCountJ = filter.jmax() - filter.jmin() + 1;
cellRangeFilter->cellCountK = filter.kmax() - filter.kmin() + 1;
return grpc::Status::OK;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcGridGeometryExtractionService::initializeMainGridPartManagerFromEclipseView()
{
if ( m_eclipseView == nullptr )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No initialized eclipse view found" );
}
auto* viewPartManager = m_eclipseView->reservoirGridPartManager();
if ( viewPartManager == nullptr )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No view part manager found for eclipse view" );
}
// Ensure static geometry parts created prior to getting part manager
viewPartManager->ensureStaticGeometryPartsCreated( RivCellSetEnum::RANGE_FILTERED );
const size_t timeStepIndex = 0;
auto rangeFilteredPartManager = viewPartManager->rangeFilteredReservoirPartManager( timeStepIndex );
if ( rangeFilteredPartManager == nullptr )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No range filtered part manager found for eclipse view" );
}
auto* mainGridPartManager = rangeFilteredPartManager->mainGridPartManager();
if ( mainGridPartManager == nullptr )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND,
"No main grid part manager found for range filtered part manager" );
}
m_mainGridPartManager = mainGridPartManager;
return grpc::Status::OK;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcGridGeometryExtractionService::loadGridGeometryFromAbsoluteFilePath( const std::string filePath )
{
QString absolutePath = QString::fromStdString( filePath );
QFileInfo projectPathInfo( absolutePath );
std::shared_ptr<RifReaderSettings> readerSettings;
readerSettings = RifReaderSettings::createGridOnlyReaderSettings();
// TODO: Set true or false?
bool createPlot = true;
bool createView = true;
auto fileOpenMetaData = RicImportGeneralDataFeature::openEclipseFilesFromFileNames( QStringList{ absolutePath },
createPlot,
createView,
readerSettings );
if ( fileOpenMetaData.createdCaseIds.empty() )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND,
QString( "loadCase: Unable to load case from %1" ).arg( absolutePath ).toStdString() );
}
return grpc::Status::OK;
}
//--------------------------------------------------------------------------------------------------
/// Helper function to get application instance and load eclipse case from given file path
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcGridGeometryExtractionService::initializeApplicationAndEclipseCaseAndEclipseViewFromAbsoluteFilePath(
const std::string filePath )
{
// Get ResInsight instance and open grid
m_application = RiaApplication::instance();
if ( m_application == nullptr )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND, "ResInsight instance not found" );
}
// Ensure existing project is closed
m_application->closeProject();
if ( filePath.empty() )
{
// For empty grid file name, use mock model
m_application->createMockModel();
}
else
{
// Load case from file name
auto status = loadGridGeometryFromAbsoluteFilePath( filePath );
if ( status.error_code() != grpc::StatusCode::OK ) return status;
}
RimProject* project = m_application->project();
if ( project == nullptr )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No project found" );
}
auto eclipseCases = project->eclipseCases();
if ( eclipseCases.empty() || eclipseCases.front() == nullptr )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No eclipse case found for project" );
}
m_eclipseCase = eclipseCases.front();
if ( m_eclipseCase->views().empty() || m_eclipseCase->views().front() == nullptr )
{
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No eclipse view found for eclipse case" );
}
m_eclipseView = dynamic_cast<RimEclipseView*>( m_eclipseCase->views().front() );
return grpc::Status::OK;
}
static bool RiaGrpcGridGeometryExtractionService_init =
RiaGrpcServiceFactory::instance()->registerCreator<RiaGrpcGridGeometryExtractionService>(
typeid( RiaGrpcGridGeometryExtractionService ).hash_code() );

View File

@ -18,7 +18,13 @@
#pragma once
#include "GridGeometryExtraction.grpc.pb.h"
#include "RiaApplication.h"
#include "RiaGrpcServiceInterface.h"
#include "RimEclipseCase.h"
#include "RimEclipseView.h"
#include "RivGridPartMgr.h"
#include "cvfArray.h"
#include <grpcpp/grpcpp.h>
@ -51,4 +57,17 @@ public:
public:
std::vector<RiaGrpcCallbackInterface*> createCallbacks() override;
private:
void resetInternalPointers();
grpc::Status loadGridGeometryFromAbsoluteFilePath( const std::string filePath );
grpc::Status initializeApplicationAndEclipseCaseAndEclipseViewFromAbsoluteFilePath( const std::string filePath );
grpc::Status initializeMainGridPartManagerFromEclipseView();
grpc::Status applyIJKCellFilterToEclipseCase( const rips::IJKIndexFilter& filter );
RiaApplication* m_application = nullptr;
RimEclipseCase* m_eclipseCase = nullptr;
RimEclipseView* m_eclipseView = nullptr;
RivGridPartMgr* m_mainGridPartManager = nullptr;
};