Implemented #310 Result info when picking

This included some refactorization to remove the command stuff out of
RiuViewer,
and to communicate the grid index via the source info struct, and not as
a cvfPart::id
This commit is contained in:
Jacob Støren
2015-06-11 11:38:51 +02:00
parent 24fb7ac584
commit 4f77afe43c
10 changed files with 930 additions and 421 deletions

View File

@@ -0,0 +1,279 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuFemResultTextBuilder.h"
#include "RigGeomechCaseData.h"
#include "RimGeoMechView.h"
#include "RimGeoMechCase.h"
#include "RigFemPartCollection.h"
#include "RigFemPart.h"
#include "RigFemPartGrid.h"
#include "RimGeoMechResultSlot.h"
#include "RigFemPartResultsCollection.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuFemResultTextBuilder::RiuFemResultTextBuilder(RimGeoMechView* reservoirView, size_t gridIndex, size_t cellIndex, size_t timeStepIndex)
{
CVF_ASSERT(reservoirView);
m_reservoirView = reservoirView;
m_gridIndex = gridIndex;
m_cellIndex = cellIndex;
m_timeStepIndex = timeStepIndex;
m_intersectionPoint = cvf::Vec3d::UNDEFINED;
m_face = cvf::StructGridInterface::NO_FACE;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuFemResultTextBuilder::setIntersectionPoint(cvf::Vec3d intersectionPoint)
{
m_intersectionPoint = intersectionPoint;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuFemResultTextBuilder::setFace(cvf::StructGridInterface::FaceType face)
{
m_face = face;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiuFemResultTextBuilder::mainResultText()
{
QString text;
text = closestNodeResultText(m_reservoirView->cellResult());
if (!text.isEmpty()) text += "\n";
QString topoText = this->topologyText("\n");
text += topoText;
text += "\n";
appendDetails(text, gridResultDetails());
return text;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiuFemResultTextBuilder::topologyText(QString itemSeparator)
{
QString text;
if (m_reservoirView->geoMechCase())
{
RigGeoMechCaseData* geomData = m_reservoirView->geoMechCase()->geoMechData();
if (geomData)
{
RigFemPart* femPart = geomData->femParts()->part(m_gridIndex);
int elementId = femPart->elmId(m_cellIndex);
text += QString("Element : Id[%1]").arg(elementId);
size_t i = 0;
size_t j = 0;
size_t k = 0;
if (geomData->femParts()->part(m_gridIndex)->structGrid()->ijkFromCellIndex(m_cellIndex, &i, &j, &k))
{
// Adjust to 1-based Eclipse indexing
i++;
j++;
k++;
cvf::Vec3d domainCoord = m_intersectionPoint; // + geomCase->femParts()->displayModelOffset();
//cvf::StructGridInterface::FaceEnum faceEnum(m_face);
//QString faceText = faceEnum.text();
//text += QString("Face : %1").arg(faceText) + itemSeparator;
//text += QString("Fem Part %1").arg(m_gridIndex) + itemSeparator;
text += QString(", ijk[%1, %2, %3]").arg(i).arg(j).arg(k) + itemSeparator;
QString formattedText;
formattedText.sprintf("Intersection point : [E: %.2f, N: %.2f, Depth: %.2f]", domainCoord.x(), domainCoord.y(), -domainCoord.z());
text += formattedText;
}
}
}
return text;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiuFemResultTextBuilder::gridResultDetails()
{
QString text;
if (m_reservoirView->geoMechCase() && m_reservoirView->geoMechCase()->geoMechData())
{
RigGeoMechCaseData* eclipseCaseData = m_reservoirView->geoMechCase()->geoMechData();
this->appendTextFromResultSlot(eclipseCaseData, m_gridIndex, m_cellIndex, m_timeStepIndex, m_reservoirView->cellResult(), &text);
if (!text.isEmpty())
{
text.prepend("-- Element result details --\n");
}
}
return text;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuFemResultTextBuilder::appendTextFromResultSlot(RigGeoMechCaseData* geomData, size_t gridIndex, size_t cellIndex, size_t timeStepIndex, RimGeoMechResultSlot* resultSlot, QString* resultInfoText)
{
if (!resultSlot)
{
return;
}
if (resultSlot->hasResult())
{
const std::vector<float>& scalarResults = geomData->femPartResults()->resultValues(resultSlot->resultAddress(), gridIndex, timeStepIndex);
if (scalarResults.size())
{
caf::AppEnum<RigFemResultPosEnum> resPosAppEnum = resultSlot->resultPositionType();
resultInfoText->append(resPosAppEnum.uiText() + ", ");
resultInfoText->append(resultSlot->resultFieldName()+ ", ") ;
resultInfoText->append(resultSlot->resultComponentName() + ":\n");
RigFemPart* femPart = geomData->femParts()->part(gridIndex);
RigElementType elmType = femPart->elementType(cellIndex);
const int* elmentConn = femPart->connectivities(cellIndex);
int elmNodeCount = RigFemTypes::elmentNodeCount(elmType);
for (int lNodeIdx = 0; lNodeIdx < elmNodeCount; ++lNodeIdx)
{
float scalarValue = std::numeric_limits<float>::infinity();
int nodeIdx = elmentConn[lNodeIdx];
if (resultSlot->resultPositionType() == RIG_NODAL)
{
scalarValue = scalarResults[nodeIdx];
}
else
{
size_t resIdx = femPart->elementNodeResultIdx(cellIndex, lNodeIdx);
scalarValue = scalarResults[resIdx];
}
resultInfoText->append(QString("\tN:%1 \t: %2\n").arg(femPart->nodes().nodeIds[nodeIdx]).arg(scalarValue));
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuFemResultTextBuilder::appendDetails(QString& text, const QString& details)
{
if (!details.isEmpty())
{
text += "\n";
text += details;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiuFemResultTextBuilder::closestNodeResultText(RimGeoMechResultSlot* resultSlot)
{
QString text;
if (!resultSlot)
{
return text;
}
if (resultSlot->hasResult())
{
if (! (m_reservoirView->geoMechCase() && m_reservoirView->geoMechCase()->geoMechData())) return text;
RigGeoMechCaseData* geomData = m_reservoirView->geoMechCase()->geoMechData();
const std::vector<float>& scalarResults = geomData->femPartResults()->resultValues(resultSlot->resultAddress(), m_gridIndex, m_timeStepIndex);
if (scalarResults.size())
{
RigFemPart* femPart = geomData->femParts()->part(m_gridIndex);
RigElementType elmType = femPart->elementType(m_cellIndex);
const int* elmentConn = femPart->connectivities(m_cellIndex);
int elmNodeCount = RigFemTypes::elmentNodeCount(elmType);
// Find the closest node
int closestLocalNode = -1;
float minDist = std::numeric_limits<float>::infinity();
for (int lNodeIdx = 0; lNodeIdx < elmNodeCount; ++lNodeIdx)
{
int nodeIdx = elmentConn[lNodeIdx];
cvf::Vec3f nodePos = femPart->nodes().coordinates[nodeIdx];
float dist = (nodePos - cvf::Vec3f(m_intersectionPoint)).lengthSquared();
if (dist < minDist)
{
closestLocalNode = lNodeIdx;
minDist = dist;
}
}
// Create a text showing the results from the closest node
if (closestLocalNode >= 0)
{
float scalarValue = std::numeric_limits<float>::infinity();
int nodeIdx = elmentConn[closestLocalNode];
if (resultSlot->resultPositionType() == RIG_NODAL)
{
scalarValue = scalarResults[nodeIdx];
}
else
{
size_t resIdx = femPart->elementNodeResultIdx(m_cellIndex, closestLocalNode);
scalarValue = scalarResults[resIdx];
}
text.append(QString("Closest result: N[%1], %2\n").arg(femPart->nodes().nodeIds[nodeIdx]).arg(scalarValue));
}
}
}
return text;
}