2015-04-20 02:02:33 -05:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Copyright (C) 2015- Statoil ASA
|
|
|
|
// Copyright (C) 2015- 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.
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include "RimGeoMechView.h"
|
|
|
|
|
|
|
|
#include "Rim3dOverlayInfoConfig.h"
|
|
|
|
#include "RiaApplication.h"
|
|
|
|
#include "RiaPreferences.h"
|
2015-04-20 09:56:26 -05:00
|
|
|
#include "RimGeoMechResultSlot.h"
|
2015-04-20 02:02:33 -05:00
|
|
|
|
2015-04-20 09:56:26 -05:00
|
|
|
#include "RiuMainWindow.h"
|
|
|
|
#include "cafCeetronPlusNavigation.h"
|
|
|
|
#include "cafCadNavigation.h"
|
|
|
|
#include "RimLegendConfig.h"
|
|
|
|
#include "cvfOverlayScalarMapperLegend.h"
|
2015-04-20 02:02:33 -05:00
|
|
|
|
2015-04-27 06:51:22 -05:00
|
|
|
#include "RimGeoMechCase.h"
|
|
|
|
#include "cvfPart.h"
|
2015-04-20 09:56:26 -05:00
|
|
|
#include "cvfViewport.h"
|
2015-04-27 06:51:22 -05:00
|
|
|
#include "cvfModelBasicList.h"
|
|
|
|
#include "cvfScene.h"
|
|
|
|
#include "RimReservoirView.h"
|
|
|
|
#include "RiuViewer.h"
|
|
|
|
#include "RivGeoMechPartMgr.h"
|
|
|
|
#include "RigGeoMechCaseData.h"
|
2015-05-04 11:16:57 -05:00
|
|
|
#include "cvfqtUtils.h"
|
2015-05-06 09:07:30 -05:00
|
|
|
#include "RigFemPartCollection.h"
|
2015-05-08 03:38:10 -05:00
|
|
|
#include "cafFrameAnimationControl.h"
|
2015-04-20 02:02:33 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CAF_PDM_SOURCE_INIT(RimGeoMechView, "GeoMechView");
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
RimGeoMechView::RimGeoMechView(void)
|
|
|
|
{
|
|
|
|
RiaApplication* app = RiaApplication::instance();
|
|
|
|
RiaPreferences* preferences = app->preferences();
|
|
|
|
CVF_ASSERT(preferences);
|
|
|
|
|
|
|
|
CAF_PDM_InitObject("Geomechanical View", ":/ReservoirView.png", "", "");
|
|
|
|
|
2015-04-20 09:56:26 -05:00
|
|
|
CAF_PDM_InitFieldNoDefault(&cellResult, "GridCellResult", "Color Result", ":/CellResult.png", "", "");
|
|
|
|
cellResult = new RimGeoMechResultSlot();
|
2015-04-20 02:02:33 -05:00
|
|
|
|
2015-04-30 10:06:01 -05:00
|
|
|
this->cellResult()->setReservoirView(this);
|
2015-04-30 03:34:15 -05:00
|
|
|
this->cellResult()->legendConfig()->setPosition(cvf::Vec2ui(10, 120));
|
|
|
|
this->cellResult()->legendConfig()->setReservoirView(this);
|
2015-05-08 03:38:10 -05:00
|
|
|
|
|
|
|
m_scaleTransform = new cvf::Transform();
|
|
|
|
m_geoMechVizModel = new RivGeoMechPartMgr();
|
|
|
|
|
2015-04-20 02:02:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
RimGeoMechView::~RimGeoMechView(void)
|
|
|
|
{
|
2015-04-30 03:34:15 -05:00
|
|
|
m_geomechCase = NULL;
|
2015-04-20 02:02:33 -05:00
|
|
|
}
|
|
|
|
|
2015-04-20 09:56:26 -05:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimGeoMechView::updateViewerWidgetWindowTitle()
|
|
|
|
{
|
|
|
|
if (m_viewer)
|
|
|
|
{
|
|
|
|
QString windowTitle;
|
2015-04-30 03:34:15 -05:00
|
|
|
if (m_geomechCase.notNull())
|
2015-04-20 09:56:26 -05:00
|
|
|
{
|
2015-04-30 03:34:15 -05:00
|
|
|
windowTitle = QString("%1 - %2").arg(m_geomechCase->caseUserDescription()).arg(name);
|
2015-04-20 09:56:26 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
windowTitle = name;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_viewer->layoutWidget()->setWindowTitle(windowTitle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimGeoMechView::loadDataAndUpdate()
|
|
|
|
{
|
2015-04-27 06:51:22 -05:00
|
|
|
if (m_geomechCase)
|
|
|
|
{
|
|
|
|
m_geomechCase->openGeoMechCase();
|
2015-05-08 03:38:10 -05:00
|
|
|
m_geoMechVizModel->clearAndSetReservoir(m_geomechCase->geoMechData(), this);
|
2015-04-27 06:51:22 -05:00
|
|
|
}
|
2015-05-08 03:38:10 -05:00
|
|
|
|
2015-04-20 09:56:26 -05:00
|
|
|
updateViewerWidget();
|
2015-04-27 06:51:22 -05:00
|
|
|
|
|
|
|
createDisplayModelAndRedraw();
|
|
|
|
|
2015-05-08 03:38:10 -05:00
|
|
|
if (cameraPosition().isIdentity())
|
|
|
|
{
|
|
|
|
setDefaultView();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
/// Todo: Work in progress
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void RimGeoMechView::updateScaleTransform()
|
|
|
|
{
|
|
|
|
CVF_ASSERT(m_scaleTransform.notNull());
|
|
|
|
|
|
|
|
cvf::Mat4d scale = cvf::Mat4d::IDENTITY;
|
|
|
|
scale(2, 2) = scaleZ();
|
|
|
|
|
|
|
|
m_scaleTransform->setLocalTransform(scale);
|
|
|
|
|
|
|
|
if (m_viewer) m_viewer->updateCachedValuesInScene();
|
2015-04-20 09:56:26 -05:00
|
|
|
}
|
|
|
|
|
2015-05-08 03:38:10 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
/// Create display model,
|
|
|
|
/// or at least empty scenes as frames that is delivered to the viewer
|
|
|
|
/// The real geometry generation is done inside RivReservoirViewGeometry and friends
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimGeoMechView::createDisplayModel()
|
|
|
|
{
|
|
|
|
if (m_viewer.isNull()) return;
|
|
|
|
|
|
|
|
if (!(m_geomechCase
|
|
|
|
&& m_geomechCase->geoMechData()
|
|
|
|
&& m_geomechCase->geoMechData()->femParts()))
|
|
|
|
return;
|
|
|
|
|
|
|
|
int partCount = m_geomechCase->geoMechData()->femParts()->partCount();
|
|
|
|
|
|
|
|
if (partCount <= 0) return;
|
|
|
|
|
|
|
|
// Define a vector containing time step indices to produce geometry for.
|
|
|
|
// First entry in this vector is used to define the geometry only result mode with no results.
|
|
|
|
std::vector<size_t> timeStepIndices;
|
|
|
|
|
|
|
|
// The one and only geometry entry
|
|
|
|
timeStepIndices.push_back(0);
|
|
|
|
|
|
|
|
// Find the number of time frames the animation needs to show the requested data.
|
|
|
|
|
|
|
|
if (isTimeStepDependentDataVisible())
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
for (i = 0; i < geoMechCase()->geoMechData()->frameCount(0, cellResult()->resultAddress()); i++)
|
|
|
|
{
|
|
|
|
timeStepIndices.push_back(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cvf::Collection<cvf::ModelBasicList> frameModels;
|
|
|
|
size_t timeIdx;
|
|
|
|
for (timeIdx = 0; timeIdx < timeStepIndices.size(); timeIdx++)
|
|
|
|
{
|
|
|
|
frameModels.push_back(new cvf::ModelBasicList);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove all existing animation frames from the viewer.
|
|
|
|
// The parts are still cached in the RivReservoir geometry and friends
|
|
|
|
|
|
|
|
bool isAnimationActive = m_viewer->isAnimationActive();
|
|
|
|
m_viewer->removeAllFrames();
|
|
|
|
|
|
|
|
for (int femPartIdx = 0; femPartIdx < partCount; ++femPartIdx)
|
|
|
|
{
|
|
|
|
cvf::ref<cvf::UByteArray> elmVisibility = m_geoMechVizModel->cellVisibility(femPartIdx);
|
|
|
|
m_geoMechVizModel->setTransform(m_scaleTransform.p());
|
|
|
|
RivElmVisibilityCalculator::computeAllVisible(elmVisibility.p(), m_geomechCase->geoMechData()->femParts()->part(femPartIdx));
|
|
|
|
m_geoMechVizModel->setCellVisibility(femPartIdx, elmVisibility.p());
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t frameIdx;
|
|
|
|
for (frameIdx = 0; frameIdx < frameModels.size(); ++frameIdx)
|
|
|
|
{
|
|
|
|
m_geoMechVizModel->appendGridPartsToModel(frameModels[frameIdx].p());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set static colors
|
|
|
|
this->updateStaticCellColors();
|
|
|
|
|
|
|
|
// Create Scenes from the frameModels
|
|
|
|
// Animation frames for results display, starts from frame 1
|
|
|
|
|
|
|
|
size_t frameIndex;
|
|
|
|
for (frameIndex = 0; frameIndex < frameModels.size(); frameIndex++)
|
|
|
|
{
|
|
|
|
cvf::ModelBasicList* model = frameModels.at(frameIndex);
|
|
|
|
model->updateBoundingBoxesRecursive();
|
|
|
|
|
|
|
|
cvf::ref<cvf::Scene> scene = new cvf::Scene;
|
|
|
|
scene->addModel(model);
|
|
|
|
|
|
|
|
if (frameIndex == 0)
|
|
|
|
m_viewer->setMainScene(scene.p());
|
|
|
|
else
|
|
|
|
m_viewer->addFrame(scene.p());
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the animation was active before recreating everything, make viewer view current frame
|
|
|
|
|
|
|
|
if (isAnimationActive || cellResult->resultFieldName() != "")
|
|
|
|
{
|
|
|
|
m_viewer->slotSetCurrentFrame(m_currentTimeStep);
|
|
|
|
}
|
|
|
|
|
|
|
|
updateLegends();
|
|
|
|
overlayInfoConfig()->update3DInfo();
|
|
|
|
}
|
2015-04-27 06:51:22 -05:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2015-05-08 03:38:10 -05:00
|
|
|
void RimGeoMechView::updateCurrentTimeStep()
|
2015-04-27 06:51:22 -05:00
|
|
|
{
|
2015-05-08 03:38:10 -05:00
|
|
|
if ((this->animationMode() && cellResult()->resultFieldName() != ""))
|
2015-04-27 06:51:22 -05:00
|
|
|
{
|
2015-05-08 03:38:10 -05:00
|
|
|
m_geoMechVizModel->updateCellResultColor(m_currentTimeStep(), this->cellResult());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->updateStaticCellColors();
|
|
|
|
}
|
|
|
|
}
|
2015-04-27 06:51:22 -05:00
|
|
|
|
2015-05-08 03:38:10 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimGeoMechView::updateStaticCellColors()
|
|
|
|
{
|
|
|
|
m_geoMechVizModel->updateCellColor(cvf::Color4f(cvf::Color3f::ORANGE));
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimGeoMechView::updateDisplayModelVisibility()
|
|
|
|
{
|
|
|
|
if (m_viewer.isNull()) return;
|
|
|
|
|
|
|
|
const cvf::uint uintSurfaceBit = surfaceBit;
|
|
|
|
const cvf::uint uintMeshSurfaceBit = meshSurfaceBit;
|
|
|
|
const cvf::uint uintFaultBit = faultBit;
|
|
|
|
const cvf::uint uintMeshFaultBit = meshFaultBit;
|
|
|
|
|
|
|
|
// Initialize the mask to show everything except the the bits controlled here
|
|
|
|
unsigned int mask = 0xffffffff & ~uintSurfaceBit & ~uintFaultBit & ~uintMeshSurfaceBit & ~uintMeshFaultBit ;
|
|
|
|
|
|
|
|
// Then turn the appropriate bits on according to the user settings
|
|
|
|
|
|
|
|
if (surfaceMode == SURFACE)
|
|
|
|
{
|
|
|
|
mask |= uintSurfaceBit;
|
|
|
|
mask |= uintFaultBit;
|
2015-04-27 06:51:22 -05:00
|
|
|
}
|
2015-05-08 03:38:10 -05:00
|
|
|
else if (surfaceMode == FAULTS)
|
|
|
|
{
|
|
|
|
mask |= uintFaultBit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (meshMode == FULL_MESH)
|
|
|
|
{
|
|
|
|
mask |= uintMeshSurfaceBit;
|
|
|
|
mask |= uintMeshFaultBit;
|
|
|
|
}
|
|
|
|
else if (meshMode == FAULTS_MESH)
|
|
|
|
{
|
|
|
|
mask |= uintMeshFaultBit;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_viewer->setEnableMask(mask);
|
|
|
|
m_viewer->update();
|
|
|
|
|
2015-04-27 06:51:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimGeoMechView::setGeoMechCase(RimGeoMechCase* gmCase)
|
|
|
|
{
|
|
|
|
m_geomechCase = gmCase;
|
|
|
|
}
|
|
|
|
|
2015-04-30 03:34:15 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimGeoMechView::resetLegendsInViewer()
|
|
|
|
{
|
|
|
|
this->cellResult()->legendConfig->recreateLegend();
|
|
|
|
|
|
|
|
m_viewer->removeAllColorLegends();
|
|
|
|
m_viewer->addColorLegendToBottomLeftCorner(this->cellResult()->legendConfig->legend());
|
|
|
|
}
|
|
|
|
|
2015-04-30 03:59:39 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimGeoMechView::updateLegends()
|
|
|
|
{
|
2015-05-04 11:16:57 -05:00
|
|
|
if (m_viewer)
|
2015-04-30 03:59:39 -05:00
|
|
|
{
|
|
|
|
m_viewer->removeAllColorLegends();
|
|
|
|
}
|
|
|
|
|
2015-05-04 11:16:57 -05:00
|
|
|
if (!m_geomechCase || !m_viewer || !m_geomechCase->geoMechData() )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
RigGeoMechCaseData* gmCase = m_geomechCase->geoMechData();
|
|
|
|
CVF_ASSERT(gmCase);
|
|
|
|
|
|
|
|
|
|
|
|
double localMin, localMax;
|
|
|
|
double localPosClosestToZero, localNegClosestToZero;
|
2015-05-08 03:38:10 -05:00
|
|
|
double globalMin, globalMax;
|
|
|
|
double globalPosClosestToZero, globalNegClosestToZero;
|
2015-05-04 11:16:57 -05:00
|
|
|
|
2015-05-08 03:38:10 -05:00
|
|
|
RigFemResultAddress resVarAddress = cellResult->resultAddress();
|
|
|
|
if (resVarAddress.fieldName != "")
|
2015-05-04 11:16:57 -05:00
|
|
|
{
|
2015-05-08 03:38:10 -05:00
|
|
|
gmCase->minMaxScalarValues(resVarAddress, 0, m_currentTimeStep, &localMin, &localMax);
|
|
|
|
gmCase->posNegClosestToZero(resVarAddress, 0, m_currentTimeStep, &localPosClosestToZero, &localNegClosestToZero);
|
2015-05-04 11:16:57 -05:00
|
|
|
|
2015-05-08 03:38:10 -05:00
|
|
|
gmCase->minMaxScalarValues(resVarAddress, 0, &globalMin, &globalMax);
|
|
|
|
gmCase->posNegClosestToZero(resVarAddress, 0, &globalPosClosestToZero, &globalNegClosestToZero);
|
2015-05-04 11:16:57 -05:00
|
|
|
|
|
|
|
|
2015-05-08 03:38:10 -05:00
|
|
|
cellResult->legendConfig->setClosestToZeroValues(globalPosClosestToZero, globalNegClosestToZero, localPosClosestToZero, localNegClosestToZero);
|
|
|
|
cellResult->legendConfig->setAutomaticRanges(globalMin, globalMax, localMin, localMax);
|
2015-05-04 11:16:57 -05:00
|
|
|
|
2015-05-08 03:38:10 -05:00
|
|
|
m_viewer->addColorLegendToBottomLeftCorner(cellResult->legendConfig->legend());
|
2015-05-04 11:16:57 -05:00
|
|
|
|
2015-05-08 03:38:10 -05:00
|
|
|
cellResult->legendConfig->legend()->setTitle(cvfqt::Utils::toString(
|
|
|
|
caf::AppEnum<RigFemResultPosEnum>(cellResult->resultPositionType()).uiText() + "\n"
|
|
|
|
+ cellResult->resultFieldName() + " " + cellResult->resultComponentName() ));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cellResult->legendConfig->setClosestToZeroValues(0, 0, 0, 0);
|
|
|
|
cellResult->legendConfig->setAutomaticRanges(cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE);
|
|
|
|
}
|
2015-05-04 11:16:57 -05:00
|
|
|
|
|
|
|
|
2015-04-30 03:59:39 -05:00
|
|
|
}
|
|
|
|
|
2015-04-30 07:19:43 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
RimGeoMechCase* RimGeoMechView::geoMechCase()
|
|
|
|
{
|
|
|
|
return m_geomechCase;
|
|
|
|
}
|
|
|
|
|
2015-05-08 03:38:10 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
/// Clamp the current timestep to actual possibilities
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimGeoMechView::clampCurrentTimestep()
|
|
|
|
{
|
|
|
|
size_t maxFrameCount = m_geomechCase->geoMechData()->frameCount(0, cellResult()->resultAddress());
|
|
|
|
|
|
|
|
if (m_currentTimeStep >= maxFrameCount ) m_currentTimeStep = (int)(maxFrameCount -1);
|
|
|
|
if (m_currentTimeStep < 0 ) m_currentTimeStep = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
bool RimGeoMechView::isTimeStepDependentDataVisible()
|
|
|
|
{
|
|
|
|
return (cellResult->resultFieldName() != "");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-04-27 06:51:22 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RivElmVisibilityCalculator::computeAllVisible(cvf::UByteArray* elmVisibilities, const RigFemPart* femPart)
|
|
|
|
{
|
|
|
|
elmVisibilities->resize(femPart->elementCount());
|
|
|
|
elmVisibilities->setAll(true);
|
|
|
|
}
|