mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#3498 Implement 2d grid projection prototype with regular grid.
This commit is contained in:
@@ -45,6 +45,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RivWellConnectionSourceInfo.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RivSimWellConnectionSourceInfo.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/Riv3dWellLogDrawSurfaceGenerator.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RivMeshLinesSourceInfo.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/Riv2dGridProjectionPartMgr.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
@@ -88,6 +89,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RivWellConnectionSourceInfo.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RivSimWellConnectionSourceInfo.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/Riv3dWellLogDrawSurfaceGenerator.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RivMeshLinesSourceInfo.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/Riv2dGridProjectionPartMgr.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
#include "Riv2dGridProjectionPartMgr.h"
|
||||
|
||||
#include "RivMeshLinesSourceInfo.h"
|
||||
#include "RivScalarMapperUtils.h"
|
||||
|
||||
#include "Rim2dGridProjection.h"
|
||||
|
||||
#include "cafEffectGenerator.h"
|
||||
|
||||
#include "cvfGeometryBuilderFaceList.h"
|
||||
#include "cvfGeometryUtils.h"
|
||||
#include "cvfMeshEdgeExtractor.h"
|
||||
#include "cvfPart.h"
|
||||
#include "cvfPrimitiveSetIndexedUInt.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Riv2dGridProjectionPartMgr::Riv2dGridProjectionPartMgr(Rim2dGridProjection* gridProjection)
|
||||
{
|
||||
m_2dGridProjection = gridProjection;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Riv2dGridProjectionPartMgr::appendProjectionToModel(cvf::ModelBasicList* model, const caf::DisplayCoordTransform* displayCoordTransform) const
|
||||
{
|
||||
cvf::ref<cvf::DrawableGeo> drawable = createDrawable(displayCoordTransform);
|
||||
if (drawable.notNull() && drawable->boundingBox().isValid())
|
||||
{
|
||||
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||
part->setDrawable(drawable.p());
|
||||
|
||||
cvf::ref<cvf::Vec2fArray> textureCoords = createTextureCoords();
|
||||
cvf::ScalarMapper* mapper = m_2dGridProjection->legendConfig()->scalarMapper();
|
||||
RivScalarMapperUtils::applyTextureResultsToPart(part.p(), textureCoords.p(), mapper, 1.0, caf::FC_NONE, true);
|
||||
|
||||
part->setSourceInfo(new RivMeshLinesSourceInfo(m_2dGridProjection.p()));
|
||||
|
||||
model->addPart(part.p());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::Vec2fArray> Riv2dGridProjectionPartMgr::createTextureCoords() const
|
||||
{
|
||||
cvf::Vec2ui patchSize = m_2dGridProjection->surfaceGridSize();
|
||||
|
||||
cvf::ref<cvf::Vec2fArray> textureCoords = new cvf::Vec2fArray(m_2dGridProjection->vertexCount());
|
||||
|
||||
for (uint j = 0; j < patchSize.y(); ++j)
|
||||
{
|
||||
for (uint i = 0; i < patchSize.x(); ++i)
|
||||
{
|
||||
double value = m_2dGridProjection->value(i, j);
|
||||
(*textureCoords)[i + j * patchSize.x()] =
|
||||
m_2dGridProjection->legendConfig()->scalarMapper()->mapToTextureCoord(value);
|
||||
}
|
||||
}
|
||||
return textureCoords;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Riv2dGridProjectionPartMgr::removeTrianglesWithNoResult(cvf::UIntArray* vertices) const
|
||||
{
|
||||
std::vector<cvf::uint> trianglesWithResult;
|
||||
|
||||
for (size_t n = 0; n < vertices->size(); n += 3)
|
||||
{
|
||||
bool anyInvalid = false;
|
||||
for (size_t t = 0; !anyInvalid && t < 3; ++t)
|
||||
{
|
||||
cvf::uint vertexNumber = (*vertices)[n + t];
|
||||
cvf::Vec2ui ij = m_2dGridProjection->ijFromGridIndex(vertexNumber);
|
||||
if (!m_2dGridProjection->hasResultAt(ij.x(), ij.y()))
|
||||
{
|
||||
anyInvalid = true;
|
||||
}
|
||||
}
|
||||
for (size_t t = 0; !anyInvalid && t < 3; ++t)
|
||||
{
|
||||
cvf::uint vertexNumber = (*vertices)[n + t];
|
||||
trianglesWithResult.push_back(vertexNumber);
|
||||
}
|
||||
}
|
||||
(*vertices) = cvf::UIntArray(trianglesWithResult);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::DrawableGeo> Riv2dGridProjectionPartMgr::createDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const
|
||||
{
|
||||
m_2dGridProjection->updateDefaultSampleSpacingFromGrid();
|
||||
m_2dGridProjection->extractGridData();
|
||||
|
||||
cvf::ref<cvf::Vec3fArray> vertexArray = new cvf::Vec3fArray;
|
||||
m_2dGridProjection->generateVertices(vertexArray.p(), displayCoordTransform);
|
||||
cvf::Vec2ui patchSize = m_2dGridProjection->surfaceGridSize();
|
||||
|
||||
// Surface
|
||||
cvf::ref<cvf::UIntArray> faceList = new cvf::UIntArray;
|
||||
cvf::GeometryUtils::tesselatePatchAsTriangles(patchSize.x(), patchSize.y(), 0u, true, faceList.p());
|
||||
|
||||
removeTrianglesWithNoResult(faceList.p());
|
||||
|
||||
cvf::ref<cvf::PrimitiveSetIndexedUInt> indexUInt = new cvf::PrimitiveSetIndexedUInt(cvf::PrimitiveType::PT_TRIANGLES, faceList.p());
|
||||
|
||||
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
|
||||
geo->addPrimitiveSet(indexUInt.p());
|
||||
geo->setVertexArray(vertexArray.p());
|
||||
return geo;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018- 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 "cafDisplayCoordTransform.h"
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfDrawableGeo.h"
|
||||
#include "cvfModelBasicList.h"
|
||||
#include "cvfObject.h"
|
||||
|
||||
class Rim2dGridProjection;
|
||||
|
||||
class Riv2dGridProjectionPartMgr : public cvf::Object
|
||||
{
|
||||
public:
|
||||
Riv2dGridProjectionPartMgr(Rim2dGridProjection* gridProjection);
|
||||
|
||||
void appendProjectionToModel(cvf::ModelBasicList* model,
|
||||
const caf::DisplayCoordTransform* displayCoordTransform) const;
|
||||
|
||||
cvf::ref<cvf::Vec2fArray> createTextureCoords() const;
|
||||
|
||||
void removeTrianglesWithNoResult(cvf::UIntArray* uintArray) const;
|
||||
private:
|
||||
cvf::ref<cvf::DrawableGeo> createDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const;
|
||||
private:
|
||||
caf::PdmPointer<Rim2dGridProjection> m_2dGridProjection;
|
||||
};
|
||||
|
||||
@@ -117,6 +117,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimWellLogFileCurveNameConfig.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellLogRftCurveNameConfig.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimDataSourceSteppingTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellLogCurveCommonDataSource.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/Rim2dGridProjection.h
|
||||
)
|
||||
|
||||
|
||||
@@ -238,6 +239,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimWellLogFileCurveNameConfig.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellLogRftCurveNameConfig.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimDataSourceSteppingTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellLogCurveCommonDataSource.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/Rim2dGridProjection.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
|
||||
366
ApplicationCode/ProjectDataModel/Rim2dGridProjection.cpp
Normal file
366
ApplicationCode/ProjectDataModel/Rim2dGridProjection.cpp
Normal file
@@ -0,0 +1,366 @@
|
||||
#include "Rim2dGridProjection.h"
|
||||
|
||||
#include "RigActiveCellInfo.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "RigResultAccessor.h"
|
||||
#include "RigResultAccessorFactory.h"
|
||||
#include "RigTernaryResultAccessor2d.h"
|
||||
|
||||
#include "RimEclipseCellColors.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimEclipseResultCase.h"
|
||||
#include "RimProject.h"
|
||||
|
||||
#include "cafPdmUiDoubleSliderEditor.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template<>
|
||||
void Rim2dGridProjection::ResultAggregation::setUp()
|
||||
{
|
||||
addItem(Rim2dGridProjection::RESULTS_MEAN_VALUE, "MEAN_VALUE", "Mean Value");
|
||||
addItem(Rim2dGridProjection::RESULTS_MIN_VALUE, "MIN_VALUE", "Min Value");
|
||||
addItem(Rim2dGridProjection::RESULTS_MAX_VALUE, "MAX_VALUE", "Max Value");
|
||||
|
||||
setDefault(Rim2dGridProjection::RESULTS_MEAN_VALUE);
|
||||
}
|
||||
}
|
||||
CAF_PDM_SOURCE_INIT(Rim2dGridProjection, "Rim2dGridProjection");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Rim2dGridProjection::Rim2dGridProjection()
|
||||
{
|
||||
CAF_PDM_InitObject("Rim2dGridProjection", ":/draw_style_meshlines_24x24.png", "", "");
|
||||
|
||||
CAF_PDM_InitField(&m_sampleSpacing, "SampleSpacing", -1.0, "Sample Spacing", "", "", "");
|
||||
m_sampleSpacing.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName());
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_resultAggregation, "ResultAggregation", "Result Aggregation", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_legendConfig, "LegendDefinition", "Legend Definition", ":/Legend.png", "", "");
|
||||
m_legendConfig = new RimRegularLegendConfig();
|
||||
|
||||
setName("2d Grid Projection");
|
||||
nameField()->uiCapability()->setUiReadOnly(true);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Rim2dGridProjection::~Rim2dGridProjection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Rim2dGridProjection::extractGridData()
|
||||
{
|
||||
cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox();
|
||||
cvf::Vec3d gridExtent = boundingBox.extent();
|
||||
|
||||
cvf::Vec2ui gridSize2d = surfaceGridSize();
|
||||
|
||||
RimEclipseResultCase* eclipseCase = nullptr;
|
||||
firstAncestorOrThisOfTypeAsserted(eclipseCase);
|
||||
|
||||
RigActiveCellInfo* activeCellInfo = eclipseCase->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL);
|
||||
|
||||
m_projected3dGridIndices.resize(vertexCount());
|
||||
for (uint j = 0; j < gridSize2d.y(); ++j)
|
||||
{
|
||||
for (uint i = 0; i < gridSize2d.x(); ++i)
|
||||
{
|
||||
cvf::Vec2d globalPos = globalPos2d(i, j);
|
||||
std::vector<size_t> allCellMatches =
|
||||
mainGrid()->findAllReservoirCellIndicesMatching2dPoint(globalPos);
|
||||
|
||||
std::vector<size_t> activeCellMatches;
|
||||
for (size_t cellIdx : allCellMatches)
|
||||
{
|
||||
if (activeCellInfo->isActive(cellIdx))
|
||||
{
|
||||
activeCellMatches.push_back(cellIdx);
|
||||
}
|
||||
}
|
||||
m_projected3dGridIndices[gridIndex(i, j)] = activeCellMatches;
|
||||
|
||||
}
|
||||
}
|
||||
m_legendConfig->setAutomaticRanges(minValue(), maxValue(), minValue(), maxValue());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Rim2dGridProjection::generateVertices(cvf::Vec3fArray* vertices, const caf::DisplayCoordTransform* displayCoordTransform)
|
||||
{
|
||||
CVF_ASSERT(vertices);
|
||||
vertices->resize(vertexCount());
|
||||
|
||||
cvf::Vec2ui gridSize2d = surfaceGridSize();
|
||||
cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox();
|
||||
|
||||
for (uint j = 0; j < gridSize2d.y(); ++j)
|
||||
{
|
||||
for (uint i = 0; i < gridSize2d.x(); ++i)
|
||||
{
|
||||
cvf::Vec2d globalPos = globalPos2d(i, j);
|
||||
cvf::Vec3d globalVertexPos(globalPos, boundingBox.max().z() + 10.0);
|
||||
cvf::Vec3f displayVertexPos(displayCoordTransform->transformToDisplayCoord(globalVertexPos));
|
||||
(*vertices)[gridIndex(i, j)] = displayVertexPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Rim2dGridProjection::maxValue() const
|
||||
{
|
||||
double maxV = 0.0;
|
||||
cvf::Vec2ui gridSize = surfaceGridSize();
|
||||
for (uint i = 0; i < gridSize.x(); ++i)
|
||||
{
|
||||
for (uint j = 0; j < gridSize.y(); ++j)
|
||||
{
|
||||
maxV = std::max(maxV, value(i, j));
|
||||
}
|
||||
}
|
||||
return maxV;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Rim2dGridProjection::minValue() const
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Rim2dGridProjection::sampleSpacing() const
|
||||
{
|
||||
return m_sampleSpacing;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Rim2dGridProjection::updateDefaultSampleSpacingFromGrid()
|
||||
{
|
||||
if (m_sampleSpacing < 0.0)
|
||||
{
|
||||
m_sampleSpacing = mainGrid()->characteristicIJCellSize();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Rim2dGridProjection::value(uint i, uint j) const
|
||||
{
|
||||
RimEclipseView* view = nullptr;
|
||||
firstAncestorOrThisOfTypeAsserted(view);
|
||||
int timeStep = view->currentTimeStep();
|
||||
|
||||
RimEclipseResultCase* eclipseCase = nullptr;
|
||||
firstAncestorOrThisOfTypeAsserted(eclipseCase);
|
||||
RimEclipseCellColors* cellColors = view->cellResult();
|
||||
|
||||
if (cellColors->isTernarySaturationSelected())
|
||||
{
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
cvf::ref<RigResultAccessor> resultAccessor =
|
||||
RigResultAccessorFactory::createFromResultDefinition(eclipseCase->eclipseCaseData(), 0, timeStep, cellColors);
|
||||
|
||||
CVF_ASSERT(resultAccessor.notNull());
|
||||
double minValue = std::numeric_limits<double>::infinity();
|
||||
double maxValue = -std::numeric_limits<double>::infinity();
|
||||
double avgValue = 0.0;
|
||||
std::vector<size_t> matchingCells = cellsAtPos2d(i, j);
|
||||
if (!matchingCells.empty())
|
||||
{
|
||||
for (size_t cellIdx : matchingCells)
|
||||
{
|
||||
double cellValue = resultAccessor->cellScalarGlobIdx(cellIdx);
|
||||
minValue = std::min(minValue, cellValue);
|
||||
maxValue = std::max(maxValue, cellValue);
|
||||
avgValue += cellValue;
|
||||
}
|
||||
avgValue /= matchingCells.size();
|
||||
}
|
||||
|
||||
switch (m_resultAggregation())
|
||||
{
|
||||
case RESULTS_MEAN_VALUE:
|
||||
return avgValue;
|
||||
case RESULTS_MAX_VALUE:
|
||||
return maxValue;
|
||||
case RESULTS_MIN_VALUE:
|
||||
return minValue;
|
||||
default:
|
||||
CVF_TIGHT_ASSERT(false);
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Rim2dGridProjection::hasResultAt(uint i, uint j) const
|
||||
{
|
||||
return !cellsAtPos2d(i, j).empty();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec2ui Rim2dGridProjection::surfaceGridSize() const
|
||||
{
|
||||
cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox();
|
||||
cvf::Vec3d gridExtent = boundingBox.extent();
|
||||
|
||||
uint projectionSizeX = static_cast<uint>(std::ceil(gridExtent.x() / m_sampleSpacing)) + 1u;
|
||||
uint projectionSizeY = static_cast<uint>(std::ceil(gridExtent.y() / m_sampleSpacing)) + 1u;
|
||||
|
||||
return cvf::Vec2ui(projectionSizeX, projectionSizeY);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
uint Rim2dGridProjection::vertexCount() const
|
||||
{
|
||||
cvf::Vec2ui gridSize2d = surfaceGridSize();
|
||||
return gridSize2d.x() * gridSize2d.y();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimRegularLegendConfig* Rim2dGridProjection::legendConfig() const
|
||||
{
|
||||
return m_legendConfig;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec2d Rim2dGridProjection::globalPos2d(uint i, uint j) const
|
||||
{
|
||||
cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox();
|
||||
cvf::Vec3d gridExtent = boundingBox.extent();
|
||||
cvf::Vec2d origin(boundingBox.min().x(), boundingBox.min().y());
|
||||
cvf::Vec2ui gridSize2d = surfaceGridSize();
|
||||
|
||||
return origin + cvf::Vec2d((i * gridExtent.x()) / (gridSize2d.x() - 1),
|
||||
(j * gridExtent.y()) / (gridSize2d.y() - 1));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<size_t>& Rim2dGridProjection::cellsAtPos2d(uint i, uint j) const
|
||||
{
|
||||
return m_projected3dGridIndices[gridIndex(i, j)];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RimEclipseResultCase* Rim2dGridProjection::eclipseCase() const
|
||||
{
|
||||
const RimEclipseResultCase* eclipseCase = nullptr;
|
||||
firstAncestorOrThisOfTypeAsserted(eclipseCase);
|
||||
return eclipseCase;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t Rim2dGridProjection::gridIndex(uint i, uint j) const
|
||||
{
|
||||
cvf::Vec2ui gridSize2d = surfaceGridSize();
|
||||
|
||||
CVF_ASSERT(i < gridSize2d.x());
|
||||
CVF_ASSERT(j < gridSize2d.y());
|
||||
|
||||
return i + j * gridSize2d.x();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec2ui Rim2dGridProjection::ijFromGridIndex(size_t index) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(index < vertexCount());
|
||||
|
||||
cvf::Vec2ui gridSize2d = surfaceGridSize();
|
||||
|
||||
unsigned int quotientX = index / gridSize2d.x();
|
||||
unsigned int remainderX = index % gridSize2d.x();
|
||||
|
||||
return cvf::Vec2ui(remainderX, quotientX);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigMainGrid* Rim2dGridProjection::mainGrid() const
|
||||
{
|
||||
RimEclipseResultCase* eclipseCase = nullptr;
|
||||
firstAncestorOrThisOfTypeAsserted(eclipseCase);
|
||||
return eclipseCase->eclipseCaseData()->mainGrid();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Rim2dGridProjection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
RimProject* proj;
|
||||
this->firstAncestorOrThisOfTypeAsserted(proj);
|
||||
if (changedField == &m_isChecked || changedField == &m_sampleSpacing || changedField == &m_resultAggregation)
|
||||
{
|
||||
proj->scheduleCreateDisplayModelAndRedrawAllViews();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Rim2dGridProjection::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute)
|
||||
{
|
||||
|
||||
if (&m_sampleSpacing == field)
|
||||
{
|
||||
caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast<caf::PdmUiDoubleSliderEditorAttribute*>(attribute);
|
||||
if (myAttr)
|
||||
{
|
||||
double characteristicSize = mainGrid()->characteristicIJCellSize();
|
||||
myAttr->m_minimum = 0.2 * characteristicSize;
|
||||
myAttr->m_maximum = 5.0 * characteristicSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Rim2dGridProjection::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/)
|
||||
{
|
||||
uiTreeOrdering.add(legendConfig());
|
||||
uiTreeOrdering.skipRemainingChildren(true);
|
||||
}
|
||||
90
ApplicationCode/ProjectDataModel/Rim2dGridProjection.h
Normal file
90
ApplicationCode/ProjectDataModel/Rim2dGridProjection.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA
|
||||
// Copyright (C) Ceetron Solutions AS
|
||||
//
|
||||
// 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 "RimRegularLegendConfig.h"
|
||||
|
||||
#include "cafDisplayCoordTransform.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include "cvfGeometryBuilderFaceList.h"
|
||||
#include "cvfVector2.h"
|
||||
|
||||
class RigMainGrid;
|
||||
class RimEclipseResultCase;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class Rim2dGridProjection : public RimCheckableNamedObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
enum ResultAggregationEnum
|
||||
{
|
||||
RESULTS_MEAN_VALUE = 0,
|
||||
RESULTS_MIN_VALUE,
|
||||
RESULTS_MAX_VALUE
|
||||
};
|
||||
typedef caf::AppEnum<ResultAggregationEnum> ResultAggregation;
|
||||
|
||||
Rim2dGridProjection();
|
||||
virtual ~Rim2dGridProjection();
|
||||
|
||||
void extractGridData();
|
||||
void generateVertices(cvf::Vec3fArray* vertices, const caf::DisplayCoordTransform* displayCoordTransform);
|
||||
double maxValue() const;
|
||||
double minValue() const;
|
||||
double sampleSpacing() const;
|
||||
void updateDefaultSampleSpacingFromGrid();
|
||||
|
||||
double value(uint i, uint j) const;
|
||||
bool hasResultAt(uint i, uint j) const;
|
||||
|
||||
cvf::Vec2ui surfaceGridSize() const;
|
||||
uint vertexCount() const;
|
||||
RimRegularLegendConfig* legendConfig() const;
|
||||
|
||||
size_t gridIndex(uint i, uint j) const;
|
||||
cvf::Vec2ui ijFromGridIndex(size_t gridIndex) const;
|
||||
protected:
|
||||
cvf::Vec2d globalPos2d(uint i, uint j) const;
|
||||
const std::vector<size_t>& cellsAtPos2d(uint i, uint j) const;
|
||||
|
||||
const RimEclipseResultCase* eclipseCase() const;
|
||||
RigMainGrid* mainGrid() const;
|
||||
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
|
||||
virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override;
|
||||
virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override;
|
||||
|
||||
protected:
|
||||
caf::PdmField<double> m_sampleSpacing;
|
||||
caf::PdmField<ResultAggregation> m_resultAggregation;
|
||||
caf::PdmChildField<RimRegularLegendConfig*> m_legendConfig;
|
||||
|
||||
std::vector<std::vector<size_t>> m_projected3dGridIndices;
|
||||
|
||||
|
||||
};
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "RigSimWellData.h"
|
||||
#include "RigVirtualPerforationTransmissibilities.h"
|
||||
|
||||
#include "Rim2dGridProjection.h"
|
||||
#include "Rim3dOverlayInfoConfig.h"
|
||||
#include "RimCellEdgeColors.h"
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
@@ -67,6 +68,7 @@
|
||||
#include "RiuSelectionManager.h"
|
||||
#include "RiuViewer.h"
|
||||
|
||||
#include "Riv2dGridProjectionPartMgr.h"
|
||||
#include "RivReservoirSimWellsPartMgr.h"
|
||||
#include "RivReservoirViewPartMgr.h"
|
||||
#include "RivSingleCellPartGenerator.h"
|
||||
@@ -158,7 +160,7 @@ RimEclipseView::RimEclipseView()
|
||||
|
||||
m_reservoirGridPartManager = new RivReservoirViewPartMgr(this);
|
||||
m_simWellsPartManager = new RivReservoirSimWellsPartMgr(this);
|
||||
|
||||
m_grid2dProjectionPartMgr = new Riv2dGridProjectionPartMgr(grid2dProjection());
|
||||
m_eclipseCase = nullptr;
|
||||
}
|
||||
|
||||
@@ -778,9 +780,23 @@ void RimEclipseView::updateCurrentTimeStep()
|
||||
simWellFracturesModelBasicList->updateBoundingBoxesRecursive();
|
||||
frameScene->addModel(simWellFracturesModelBasicList.p());
|
||||
}
|
||||
if (m_2dGridProjection->isChecked())
|
||||
{
|
||||
cvf::String name = "Grid2dProjection";
|
||||
this->removeModelByName(frameScene, name);
|
||||
|
||||
cvf::ref<cvf::ModelBasicList> grid2dProjectionModelBasicList = new cvf::ModelBasicList;
|
||||
grid2dProjectionModelBasicList->setName(name);
|
||||
|
||||
cvf::ref<caf::DisplayCoordTransform> transForm = this->displayCoordTransform();
|
||||
|
||||
m_grid2dProjectionPartMgr->appendProjectionToModel(grid2dProjectionModelBasicList.p(), transForm.p());
|
||||
grid2dProjectionModelBasicList->updateBoundingBoxesRecursive();
|
||||
frameScene->addModel(grid2dProjectionModelBasicList.p());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_overlayInfoConfig()->update3DInfo();
|
||||
|
||||
// Invisible Wells are marked as read only when "show wells intersecting visible cells" is enabled
|
||||
@@ -1508,7 +1524,7 @@ void RimEclipseView::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering
|
||||
|
||||
uiTreeOrdering.add(m_rangeFilterCollection());
|
||||
uiTreeOrdering.add(m_propertyFilterCollection());
|
||||
|
||||
uiTreeOrdering.add(m_2dGridProjection());
|
||||
uiTreeOrdering.skipRemainingChildren(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ class RimStimPlanColors;
|
||||
class RimVirtualPerforationResults;
|
||||
class RiuViewer;
|
||||
class RivReservoirSimWellsPartMgr;
|
||||
class Riv2dGridProjectionPartMgr;
|
||||
class RivIntersectionPartMgr;
|
||||
class RivReservoirViewPartMgr;
|
||||
|
||||
@@ -198,6 +199,7 @@ private:
|
||||
|
||||
cvf::ref<RivReservoirViewPartMgr> m_reservoirGridPartManager;
|
||||
cvf::ref<RivReservoirSimWellsPartMgr> m_simWellsPartManager;
|
||||
cvf::ref<Riv2dGridProjectionPartMgr> m_grid2dProjectionPartMgr;
|
||||
|
||||
std::vector<RivCellSetEnum> m_visibleGridParts;
|
||||
};
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "RiaApplication.h"
|
||||
|
||||
#include "Rim2dGridProjection.h"
|
||||
#include "Rim3dOverlayInfoConfig.h"
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
#include "RimGridCollection.h"
|
||||
@@ -62,12 +63,16 @@ RimGridView::RimGridView()
|
||||
m_gridCollection.uiCapability()->setUiHidden(true);
|
||||
m_gridCollection = new RimGridCollection();
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_2dGridProjection, "Grid2dProjection", "2d Grid Projection", "", "", "");
|
||||
m_2dGridProjection = new Rim2dGridProjection();
|
||||
|
||||
m_previousGridModeMeshLinesWasFaults = false;
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_overlayInfoConfig, "OverlayInfoConfig", "Info Box", "", "", "");
|
||||
m_overlayInfoConfig = new Rim3dOverlayInfoConfig();
|
||||
m_overlayInfoConfig->setReservoirView(this);
|
||||
m_overlayInfoConfig.uiCapability()->setUiHidden(true);
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -261,6 +266,14 @@ bool RimGridView::isGridVisualizationMode() const
|
||||
return this->m_gridCollection->isActive();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Rim2dGridProjection* RimGridView::grid2dProjection() const
|
||||
{
|
||||
return m_2dGridProjection().p();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "cvfBase.h"
|
||||
#include "cvfArray.h"
|
||||
|
||||
class Rim2dGridProjection;
|
||||
class Rim3dOverlayInfoConfig;
|
||||
class RimIntersectionCollection;
|
||||
class RimPropertyFilterCollection;
|
||||
@@ -58,6 +59,8 @@ public:
|
||||
|
||||
virtual bool isGridVisualizationMode() const override;
|
||||
|
||||
Rim2dGridProjection* grid2dProjection() const;
|
||||
|
||||
protected:
|
||||
virtual void initAfterRead() override;
|
||||
virtual void onTimeStepChanged() override;
|
||||
@@ -72,7 +75,7 @@ protected: // Fields
|
||||
caf::PdmChildField<RimCellRangeFilterCollection*> m_rangeFilterCollection;
|
||||
caf::PdmChildField<RimCellRangeFilterCollection*> m_overrideRangeFilterCollection;
|
||||
caf::PdmChildField<RimGridCollection*> m_gridCollection;
|
||||
|
||||
caf::PdmChildField<Rim2dGridProjection*> m_2dGridProjection;
|
||||
protected:
|
||||
cvf::ref<cvf::UByteArray> m_currentReservoirCellVisibility;
|
||||
|
||||
|
||||
@@ -80,6 +80,42 @@ int RigHexIntersectionTools::lineHexCellIntersection(const cvf::Vec3d p1,
|
||||
return intersectionCount;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigHexIntersectionTools::lineIntersectsHexCell(const cvf::Vec3d p1, const cvf::Vec3d p2, const cvf::Vec3d hexCorners[8])
|
||||
{
|
||||
for (int face = 0; face < 6; ++face)
|
||||
{
|
||||
cvf::ubyte faceVertexIndices[4];
|
||||
cvf::StructGridInterface::cellFaceVertexIndices(static_cast<cvf::StructGridInterface::FaceType>(face), faceVertexIndices);
|
||||
|
||||
cvf::Vec3d intersection;
|
||||
bool isEntering = false;
|
||||
cvf::Vec3d faceCenter = cvf::GeometryTools::computeFaceCenter(hexCorners[faceVertexIndices[0]],
|
||||
hexCorners[faceVertexIndices[1]],
|
||||
hexCorners[faceVertexIndices[2]],
|
||||
hexCorners[faceVertexIndices[3]]);
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
int next = i < 3 ? i + 1 : 0;
|
||||
|
||||
int intsStatus = cvf::GeometryTools::intersectLineSegmentTriangle(p1, p2,
|
||||
hexCorners[faceVertexIndices[i]],
|
||||
hexCorners[faceVertexIndices[next]],
|
||||
faceCenter,
|
||||
&intersection,
|
||||
&isEntering);
|
||||
if (intsStatus == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -61,6 +61,10 @@ struct RigHexIntersectionTools
|
||||
const size_t hexIndex,
|
||||
std::vector<HexIntersectionInfo>* intersections);
|
||||
|
||||
static bool lineIntersectsHexCell(const cvf::Vec3d p1,
|
||||
const cvf::Vec3d p2,
|
||||
const cvf::Vec3d hexCorners[8]);
|
||||
|
||||
static bool isPointInCell(const cvf::Vec3d point, const cvf::Vec3d hexCorners[8]);
|
||||
|
||||
static bool planeHexCellIntersection(cvf::Vec3d* hexCorners,
|
||||
|
||||
@@ -119,6 +119,36 @@ size_t RigMainGrid::findReservoirCellIndexFromPoint(const cvf::Vec3d& point) con
|
||||
return cellContainingPoint;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<size_t> RigMainGrid::findAllReservoirCellIndicesMatching2dPoint(const cvf::Vec2d& point2d) const
|
||||
{
|
||||
cvf::BoundingBox gridBoundingVox = boundingBox();
|
||||
cvf::Vec3d highestPoint(point2d, gridBoundingVox.max().z());
|
||||
cvf::Vec3d lowestPoint (point2d, gridBoundingVox.min().z());
|
||||
|
||||
cvf::BoundingBox rayBBox;
|
||||
rayBBox.add(highestPoint);
|
||||
rayBBox.add(lowestPoint);
|
||||
|
||||
std::vector<size_t> cellIndices;
|
||||
m_mainGrid->findIntersectingCells(rayBBox, &cellIndices);
|
||||
|
||||
cvf::Vec3d hexCorners[8];
|
||||
for (size_t cellIndex : cellIndices)
|
||||
{
|
||||
m_mainGrid->cellCornerVertices(cellIndex, hexCorners);
|
||||
|
||||
if (RigHexIntersectionTools::lineIntersectsHexCell(highestPoint, lowestPoint, hexCorners))
|
||||
{
|
||||
cellIndices.push_back(cellIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return cellIndices;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
const RigCell& cellByGridAndGridLocalCellIdx(size_t gridIdx, size_t gridLocalCellIdx) const;
|
||||
size_t reservoirCellIndexByGridAndGridLocalCellIndex(size_t gridIdx, size_t gridLocalCellIdx) const;
|
||||
size_t findReservoirCellIndexFromPoint(const cvf::Vec3d& point) const;
|
||||
|
||||
std::vector<size_t> findAllReservoirCellIndicesMatching2dPoint(const cvf::Vec2d& point2d) const;
|
||||
void addLocalGrid(RigLocalGrid* localGrid);
|
||||
size_t gridCount() const { return m_localGrids.size() + 1; }
|
||||
RigGridBase* gridByIndex(size_t localGridIndex);
|
||||
|
||||
Reference in New Issue
Block a user