Tensor flow improvements

New GUI settings for tensor length control, fluid selection, NNC data selection and aggregated visualization. Possibility to change vector start position. Improved vector visualization.
This commit is contained in:
Ruben Thoms 2020-09-29 09:47:38 +02:00 committed by Magne Sjaastad
parent 2feb9d0cd7
commit cc5335d46f
7 changed files with 617 additions and 213 deletions

View File

@ -30,9 +30,12 @@
#include "RigEclipseResultAddress.h" #include "RigEclipseResultAddress.h"
#include "RigMainGrid.h" #include "RigMainGrid.h"
#include "cafDisplayCoordTransform.h"
#include "cafEffectGenerator.h" #include "cafEffectGenerator.h"
#include "cvfDrawableGeo.h" #include "cvfDrawableGeo.h"
#include "cvfGeometryTools.h"
#include "cvfModelBasicList.h" #include "cvfModelBasicList.h"
#include "cvfPart.h" #include "cvfPart.h"
#include "cvfPrimitiveSetIndexedUInt.h" #include "cvfPrimitiveSetIndexedUInt.h"
@ -100,30 +103,39 @@ void RivElementVectorResultPartMgr::appendDynamicGeometryPartsToModel( cvf::Mode
} }
float arrowScaling = arrowConstantScaling; float arrowScaling = arrowConstantScaling;
if ( result->scaleMethod() == RimElementVectorResult::RESULT ) if ( result->scaleMethod() == RimElementVectorResult::ScaleMethod::RESULT )
{ {
arrowScaling = arrowConstantScaling / maxAbsResult; arrowScaling = arrowConstantScaling / maxAbsResult;
} }
if ( result->scaleMethod() == RimElementVectorResult::ScaleMethod::RESULT_LOG )
{
arrowScaling = result->sizeScale() * scaleLogarithmically( maxAbsResult );
}
std::vector<RigEclipseResultAddress> addresses; std::vector<RigEclipseResultAddress> addresses;
result->resultAddressIJK( addresses ); result->resultAddressesIJK( addresses );
std::vector<cvf::StructGridInterface::FaceType> directions; std::vector<cvf::StructGridInterface::FaceType> directions;
std::vector<RigEclipseResultAddress> resultAddresses; std::vector<RigEclipseResultAddress> resultAddresses;
if ( result->showVectorI() )
for ( size_t fluidIndex = 0; fluidIndex < addresses.size(); fluidIndex += 3 )
{ {
directions.push_back( cvf::StructGridInterface::POS_I ); if ( result->showVectorI() )
resultAddresses.push_back( addresses[0] ); {
} if ( fluidIndex == 0 ) directions.push_back( cvf::StructGridInterface::POS_I );
if ( result->showVectorJ() ) resultAddresses.push_back( addresses[0 + fluidIndex] );
{ }
directions.push_back( cvf::StructGridInterface::POS_J ); if ( result->showVectorJ() )
resultAddresses.push_back( addresses[1] ); {
} if ( fluidIndex == 0 ) directions.push_back( cvf::StructGridInterface::POS_J );
if ( result->showVectorK() ) resultAddresses.push_back( addresses[1 + fluidIndex] );
{ }
directions.push_back( cvf::StructGridInterface::POS_K ); if ( result->showVectorK() )
resultAddresses.push_back( addresses[2] ); {
if ( fluidIndex == 0 ) directions.push_back( cvf::StructGridInterface::POS_K );
resultAddresses.push_back( addresses[2 + fluidIndex] );
}
} }
RigCaseCellResultsData* resultsData = eclipseCaseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL ); RigCaseCellResultsData* resultsData = eclipseCaseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
@ -136,25 +148,135 @@ void RivElementVectorResultPartMgr::appendDynamicGeometryPartsToModel( cvf::Mode
{ {
if ( !cells[gcIdx].isInvalid() && activeCellInfo->isActive( gcIdx ) ) if ( !cells[gcIdx].isInvalid() && activeCellInfo->isActive( gcIdx ) )
{ {
for ( int dir = 0; dir < static_cast<int>( directions.size() ); dir++ ) size_t resultIdx = activeCellInfo->cellResultIndex( gcIdx );
if ( result->vectorView() == RimElementVectorResult::VectorView::INDIVIDUAL )
{ {
size_t resultIdx = activeCellInfo->cellResultIndex( gcIdx ); for ( int dir = 0; dir < static_cast<int>( directions.size() ); dir++ )
double resultValue = resultsData->cellScalarResults( resultAddresses[dir], timeStepIndex ).at( resultIdx );
if ( std::abs( resultValue ) >= result->threshold() )
{ {
double resultValue = 0.0;
for ( size_t flIdx = dir; flIdx < resultAddresses.size(); flIdx += directions.size() )
{
resultValue +=
resultsData->cellScalarResults( resultAddresses[flIdx], timeStepIndex ).at( resultIdx );
}
if ( std::abs( resultValue ) >= result->threshold() )
{
cvf::Vec3d faceCenter = cells[gcIdx].faceCenter( directions[dir] ) - offset;
cvf::Vec3d cellCenter = cells[gcIdx].center() - offset;
cvf::Vec3d faceNormal = ( faceCenter - cellCenter ).getNormalized() * arrowScaling;
if ( result->scaleMethod() == RimElementVectorResult::ScaleMethod::RESULT )
{
faceNormal *= std::abs( resultValue );
}
else if ( result->scaleMethod() == RimElementVectorResult::ScaleMethod::RESULT_LOG )
{
faceNormal *= std::abs( scaleLogarithmically( std::abs( resultValue ) ) );
}
tensorVisualizations.push_back(
ElementVectorResultVisualization( faceCenter,
faceNormal,
resultValue,
std::cbrt( cells[gcIdx].volume() / 3.0 ) ) );
}
}
}
else if ( result->vectorView() == RimElementVectorResult::VectorView::AGGREGATED )
{
cvf::Vec3d aggregatedVector;
cvf::Vec3d aggregatedResult;
for ( int dir = 0; dir < static_cast<int>( directions.size() ); dir++ )
{
double resultValue = 0.0;
for ( size_t flIdx = dir; flIdx < resultAddresses.size(); flIdx += directions.size() )
{
resultValue +=
resultsData->cellScalarResults( resultAddresses[flIdx], timeStepIndex ).at( resultIdx );
}
cvf::Vec3d faceCenter = cells[gcIdx].faceCenter( directions[dir] ) - offset; cvf::Vec3d faceCenter = cells[gcIdx].faceCenter( directions[dir] ) - offset;
cvf::Vec3d cellCenter = cells[gcIdx].center() - offset; cvf::Vec3d cellCenter = cells[gcIdx].center() - offset;
cvf::Vec3d faceNormal = ( faceCenter - cellCenter ).getNormalized() * arrowScaling; cvf::Vec3d faceNormal = ( faceCenter - cellCenter ).getNormalized() * arrowScaling;
if ( result->scaleMethod() == RimElementVectorResult::RESULT ) aggregatedVector += faceNormal;
if ( result->scaleMethod() == RimElementVectorResult::ScaleMethod::RESULT )
{ {
faceNormal *= std::abs( resultValue ); faceNormal *= resultValue;
}
else if ( result->scaleMethod() == RimElementVectorResult::ScaleMethod::RESULT_LOG )
{
faceNormal *= ( 1.0 - static_cast<double>( std::signbit( resultValue ) ) * 2.0 ) *
scaleLogarithmically( std::abs( resultValue ) );
} }
tensorVisualizations.push_back( aggregatedVector += faceNormal;
ElementVectorResultVisualization( faceCenter, faceNormal, resultValue ) ); aggregatedResult += ( faceCenter - cellCenter ).getNormalized() * resultValue;
} }
if ( aggregatedVector.length() > 0 )
{
tensorVisualizations.push_back(
ElementVectorResultVisualization( cells[gcIdx].center() - offset,
aggregatedVector,
aggregatedResult.length(),
std::cbrt( cells[gcIdx].volume() / 3.0 ) ) );
}
}
}
}
RigNNCData* nncData = eclipseCaseData->mainGrid()->nncData();
size_t numNncConnections = nncData->connections().size();
if ( result->showNncData() )
{
std::vector<const std::vector<std::vector<double>>*> nncResultVals;
std::vector<RigEclipseResultAddress> combinedAddresses;
result->resultAddressesCombined( combinedAddresses );
for ( size_t flIdx = 0; flIdx < combinedAddresses.size(); flIdx++ )
{
if ( combinedAddresses[flIdx].m_resultCatType == RiaDefines::ResultCatType::DYNAMIC_NATIVE )
{
nncResultVals.push_back( nncData->dynamicConnectionScalarResult( combinedAddresses[flIdx] ) );
}
}
for ( size_t nIdx = 0; nIdx < numNncConnections; ++nIdx )
{
const RigConnection& conn = nncData->connections()[nIdx];
if ( conn.polygon().size() )
{
double resultValue = 0.0;
for ( size_t flIdx = 0; flIdx < nncResultVals.size(); flIdx++ )
{
if ( nIdx < nncResultVals.at( flIdx )->at( timeStepIndex ).size() )
{
resultValue += nncResultVals.at( flIdx )->at( timeStepIndex )[nIdx];
}
}
cvf::Vec3d connCenter =
static_cast<cvf::Vec3d>( cvf::GeometryTools::computePolygonCenter<cvf::Vec3f>( conn.polygon() ) );
cvf::Vec3d faceCenter = cells[conn.c1GlobIdx()].faceCenter( conn.face() ) - offset;
cvf::Vec3d cellCenter = cells[conn.c1GlobIdx()].center() - offset;
cvf::Vec3d connNormal = ( faceCenter - cellCenter ).getNormalized() * arrowScaling;
if ( result->scaleMethod() == RimElementVectorResult::ScaleMethod::RESULT )
{
connNormal *= std::abs( resultValue );
}
else if ( result->scaleMethod() == RimElementVectorResult::ScaleMethod::RESULT_LOG )
{
connNormal *= scaleLogarithmically( std::abs( resultValue ) );
}
tensorVisualizations.push_back(
ElementVectorResultVisualization( connCenter - offset,
connNormal,
resultValue,
std::cbrt( cells[conn.c1GlobIdx()].volume() / 3.0 ) ) );
} }
} }
} }
@ -175,11 +297,14 @@ cvf::ref<cvf::Part>
RivElementVectorResultPartMgr::createPart( const RimElementVectorResult& result, RivElementVectorResultPartMgr::createPart( const RimElementVectorResult& result,
const std::vector<ElementVectorResultVisualization>& tensorVisualizations ) const const std::vector<ElementVectorResultVisualization>& tensorVisualizations ) const
{ {
std::vector<uint> indices; std::vector<uint> shaftIndices;
indices.reserve( tensorVisualizations.size() * 5 ); shaftIndices.reserve( tensorVisualizations.size() * 2 );
std::vector<uint> headIndices;
headIndices.reserve( tensorVisualizations.size() * 6 );
std::vector<cvf::Vec3f> vertices; std::vector<cvf::Vec3f> vertices;
vertices.reserve( tensorVisualizations.size() * 5 ); vertices.reserve( tensorVisualizations.size() * 7 );
uint counter = 0; uint counter = 0;
for ( ElementVectorResultVisualization tensor : tensorVisualizations ) for ( ElementVectorResultVisualization tensor : tensorVisualizations )
@ -189,21 +314,34 @@ cvf::ref<cvf::Part>
vertices.push_back( vertex ); vertices.push_back( vertex );
} }
for ( const uint& index : createArrowIndices( counter ) ) for ( const uint& index : createArrowShaftIndices( counter ) )
{ {
indices.push_back( index ); shaftIndices.push_back( index );
} }
counter += 5; for ( const uint& index : createArrowHeadIndices( counter ) )
{
headIndices.push_back( index );
}
counter += 7;
} }
cvf::ref<cvf::PrimitiveSetIndexedUInt> indexedUInt = new cvf::PrimitiveSetIndexedUInt( cvf::PrimitiveType::PT_LINES ); cvf::ref<cvf::PrimitiveSetIndexedUInt> indexedUIntShaft =
cvf::ref<cvf::UIntArray> indexArray = new cvf::UIntArray( indices ); new cvf::PrimitiveSetIndexedUInt( cvf::PrimitiveType::PT_LINES );
cvf::ref<cvf::UIntArray> indexArrayShaft = new cvf::UIntArray( shaftIndices );
cvf::ref<cvf::PrimitiveSetIndexedUInt> indexedUIntHead =
new cvf::PrimitiveSetIndexedUInt( cvf::PrimitiveType::PT_TRIANGLES );
cvf::ref<cvf::UIntArray> indexArrayHead = new cvf::UIntArray( headIndices );
cvf::ref<cvf::DrawableGeo> drawable = new cvf::DrawableGeo(); cvf::ref<cvf::DrawableGeo> drawable = new cvf::DrawableGeo();
indexedUInt->setIndices( indexArray.p() ); indexedUIntShaft->setIndices( indexArrayShaft.p() );
drawable->addPrimitiveSet( indexedUInt.p() ); drawable->addPrimitiveSet( indexedUIntShaft.p() );
indexedUIntHead->setIndices( indexArrayHead.p() );
drawable->addPrimitiveSet( indexedUIntHead.p() );
cvf::ref<cvf::Vec3fArray> vertexArray = new cvf::Vec3fArray( vertices ); cvf::ref<cvf::Vec3fArray> vertexArray = new cvf::Vec3fArray( vertices );
drawable->setVertexArray( vertexArray.p() ); drawable->setVertexArray( vertexArray.p() );
@ -220,7 +358,7 @@ cvf::ref<cvf::Part>
cvf::ref<cvf::Effect> effect; cvf::ref<cvf::Effect> effect;
auto vectorColors = result.vectorColors(); auto vectorColors = result.vectorColors();
if ( vectorColors == RimElementVectorResult::RESULT_COLORS ) if ( vectorColors == RimElementVectorResult::TensorColors::RESULT_COLORS )
{ {
activeScalerMapper = result.legendConfig()->scalarMapper(); activeScalerMapper = result.legendConfig()->scalarMapper();
createResultColorTextureCoords( lineTexCoords.p(), tensorVisualizations, activeScalerMapper ); createResultColorTextureCoords( lineTexCoords.p(), tensorVisualizations, activeScalerMapper );
@ -255,12 +393,12 @@ void RivElementVectorResultPartMgr::createResultColorTextureCoords(
CVF_ASSERT( textureCoords ); CVF_ASSERT( textureCoords );
CVF_ASSERT( mapper ); CVF_ASSERT( mapper );
size_t vertexCount = elementVectorResultVisualizations.size() * 5; size_t vertexCount = elementVectorResultVisualizations.size() * 7;
if ( textureCoords->size() != vertexCount ) textureCoords->reserve( vertexCount ); if ( textureCoords->size() != vertexCount ) textureCoords->reserve( vertexCount );
for ( auto evrViz : elementVectorResultVisualizations ) for ( auto evrViz : elementVectorResultVisualizations )
{ {
for ( size_t vxIdx = 0; vxIdx < 5; ++vxIdx ) for ( size_t vxIdx = 0; vxIdx < 7; ++vxIdx )
{ {
cvf::Vec2f texCoord = mapper->mapToTextureCoord( evrViz.result ); cvf::Vec2f texCoord = mapper->mapToTextureCoord( evrViz.result );
textureCoords->add( texCoord ); textureCoords->add( texCoord );
@ -271,32 +409,48 @@ void RivElementVectorResultPartMgr::createResultColorTextureCoords(
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::array<cvf::Vec3f, 5> std::array<cvf::Vec3f, 7>
RivElementVectorResultPartMgr::createArrowVertices( const ElementVectorResultVisualization& evrViz ) const RivElementVectorResultPartMgr::createArrowVertices( const ElementVectorResultVisualization& evrViz ) const
{ {
std::array<cvf::Vec3f, 5> vertices; std::array<cvf::Vec3f, 7> vertices;
RimElementVectorResult* result = m_rimReservoirView->elementVectorResult();
if ( !result ) return vertices;
cvf::Vec3f headTop = evrViz.faceCenter + evrViz.faceNormal; cvf::Vec3f headTop = evrViz.faceCenter + evrViz.faceNormal;
cvf::Vec3f shaftStart = evrViz.faceCenter; cvf::Vec3f shaftStart = evrViz.faceCenter;
if ( result->vectorSuraceCrossingLocation() == RimElementVectorResult::VectorSurfaceCrossingLocation::VECTOR_CENTER &&
result->vectorView() == RimElementVectorResult::VectorView::INDIVIDUAL )
{
headTop = evrViz.faceCenter + evrViz.faceNormal / 2.0;
shaftStart = evrViz.faceCenter - evrViz.faceNormal / 2.0;
}
// Flip arrow for negative results // Flip arrow for negative results
if ( evrViz.result < 0 ) if ( evrViz.result < 0 && result->vectorView() != RimElementVectorResult::VectorView::AGGREGATED )
{ {
std::swap( headTop, shaftStart ); std::swap( headTop, shaftStart );
} }
float headWidth = 0.05 * evrViz.faceNormal.length(); // float headWidth = 0.05 * evrViz.faceNormal.length();
float headLength = std::min<float>( evrViz.characteristicCellSize / 5.0f, ( headTop - shaftStart ).length() / 2.0 );
cvf::Vec3f headBottom = headTop - ( headTop - shaftStart ) * 0.2f; // A fixed size is preferred here
cvf::Vec3f headBottom = headTop - ( headTop - shaftStart ).getNormalized() * headLength;
// cvf::Vec3f headBottom = headTop - ( headTop - shaftStart ) * 0.2f;
cvf::Vec3f headBottomDirection = evrViz.faceNormal ^ evrViz.faceCenter; cvf::Vec3f headBottomDirection1 = evrViz.faceNormal ^ evrViz.faceCenter;
cvf::Vec3f arrowBottomSegment = headBottomDirection.getNormalized() * headWidth; cvf::Vec3f headBottomDirection2 = headBottomDirection1 ^ evrViz.faceNormal;
cvf::Vec3f arrowBottomSegment1 = headBottomDirection1.getNormalized() * headLength / 8.0f;
cvf::Vec3f arrowBottomSegment2 = headBottomDirection2.getNormalized() * headLength / 8.0f;
vertices[0] = shaftStart; vertices[0] = shaftStart;
vertices[1] = headBottom; vertices[1] = headBottom;
vertices[2] = headBottom + arrowBottomSegment; vertices[2] = headBottom + arrowBottomSegment1;
vertices[3] = headBottom - arrowBottomSegment; vertices[3] = headBottom - arrowBottomSegment1;
vertices[4] = headTop; vertices[4] = headTop;
vertices[5] = headBottom + arrowBottomSegment2;
vertices[6] = headBottom - arrowBottomSegment2;
return vertices; return vertices;
} }
@ -304,18 +458,41 @@ std::array<cvf::Vec3f, 5>
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::array<uint, 8> RivElementVectorResultPartMgr::createArrowIndices( uint startIndex ) const std::array<uint, 2> RivElementVectorResultPartMgr::createArrowShaftIndices( uint startIndex ) const
{ {
std::array<uint, 8> indices; std::array<uint, 2> indices;
indices[0] = startIndex; indices[0] = startIndex;
indices[1] = startIndex + 1; indices[1] = startIndex + 1;
indices[2] = startIndex + 2;
indices[3] = startIndex + 3;
indices[4] = startIndex + 3;
indices[5] = startIndex + 4;
indices[6] = startIndex + 4;
indices[7] = startIndex + 2;
return indices; return indices;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::array<uint, 6> RivElementVectorResultPartMgr::createArrowHeadIndices( uint startIndex ) const
{
std::array<uint, 6> indices;
indices[0] = startIndex + 2;
indices[1] = startIndex + 3;
indices[2] = startIndex + 4;
indices[3] = startIndex + 5;
indices[4] = startIndex + 6;
indices[5] = startIndex + 4;
return indices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RivElementVectorResultPartMgr::scaleLogarithmically( double value ) const
{
if ( value <= 1.0 )
{
value += 1.0;
}
return std::log10( value );
}

View File

@ -54,16 +54,18 @@ public:
private: private:
struct ElementVectorResultVisualization struct ElementVectorResultVisualization
{ {
ElementVectorResultVisualization( cvf::Vec3d faceCenter, cvf::Vec3d faceNormal, double result ) ElementVectorResultVisualization( cvf::Vec3d faceCenter, cvf::Vec3d faceNormal, double result, double characteristicCellSize )
: faceCenter( faceCenter ) : faceCenter( faceCenter )
, faceNormal( faceNormal ) , faceNormal( faceNormal )
, result( result ) , result( result )
, characteristicCellSize( characteristicCellSize )
{ {
} }
cvf::Vec3f faceCenter; cvf::Vec3f faceCenter;
cvf::Vec3f faceNormal; cvf::Vec3f faceNormal;
double result; double result;
double characteristicCellSize;
}; };
private: private:
@ -75,8 +77,11 @@ private:
const std::vector<ElementVectorResultVisualization>& elementVectorResultVisualizations, const std::vector<ElementVectorResultVisualization>& elementVectorResultVisualizations,
const cvf::ScalarMapper* mapper ); const cvf::ScalarMapper* mapper );
std::array<cvf::Vec3f, 5> createArrowVertices( const ElementVectorResultVisualization& tensorVisualization ) const; std::array<cvf::Vec3f, 7> createArrowVertices( const ElementVectorResultVisualization& tensorVisualization ) const;
std::array<uint, 8> createArrowIndices( uint startIndex ) const; std::array<uint, 2> createArrowShaftIndices( uint startIndex ) const;
std::array<uint, 6> createArrowHeadIndices( uint startIndex ) const;
double scaleLogarithmically( double value ) const;
private: private:
caf::PdmPointer<RimEclipseView> m_rimReservoirView; caf::PdmPointer<RimEclipseView> m_rimReservoirView;

View File

@ -20,6 +20,8 @@
#include "RigCaseCellResultsData.h" #include "RigCaseCellResultsData.h"
#include "RigEclipseCaseData.h" #include "RigEclipseCaseData.h"
#include "RigEclipseResultAddress.h" #include "RigEclipseResultAddress.h"
#include "RigMainGrid.h"
#include "RigNNCData.h"
#include "Rim3dView.h" #include "Rim3dView.h"
#include "RimEclipseCase.h" #include "RimEclipseCase.h"
@ -38,19 +40,38 @@ namespace caf
template <> template <>
void AppEnum<RimElementVectorResult::TensorColors>::setUp() void AppEnum<RimElementVectorResult::TensorColors>::setUp()
{ {
addItem( RimElementVectorResult::RESULT_COLORS, "RESULT_COLORS", "Result Colors" ); addItem( RimElementVectorResult::TensorColors::RESULT_COLORS, "RESULT_COLORS", "Result Colors" );
addItem( RimElementVectorResult::UNIFORM_COLOR, "UNIFORM_COLOR", "Uniform" ); addItem( RimElementVectorResult::TensorColors::UNIFORM_COLOR, "UNIFORM_COLOR", "Uniform" );
setDefault( RimElementVectorResult::RESULT_COLORS ); setDefault( RimElementVectorResult::TensorColors::RESULT_COLORS );
} }
template <> template <>
void AppEnum<RimElementVectorResult::ScaleMethod>::setUp() void AppEnum<RimElementVectorResult::ScaleMethod>::setUp()
{ {
addItem( RimElementVectorResult::RESULT, "RESULT", "Result" ); addItem( RimElementVectorResult::ScaleMethod::RESULT, "RESULT", "Result" );
addItem( RimElementVectorResult::CONSTANT, "CONSTANT", "Constant" ); addItem( RimElementVectorResult::ScaleMethod::RESULT_LOG, "RESULT_LOG", "Result (logarithmic scaling)" );
addItem( RimElementVectorResult::ScaleMethod::CONSTANT, "CONSTANT", "Constant" );
setDefault( RimElementVectorResult::RESULT ); setDefault( RimElementVectorResult::ScaleMethod::RESULT );
}
template <>
void AppEnum<RimElementVectorResult::VectorView>::setUp()
{
addItem( RimElementVectorResult::VectorView::AGGREGATED, "AGGREGATED", "Aggregated" );
addItem( RimElementVectorResult::VectorView::INDIVIDUAL, "INDIVIDUAL", "Individual" );
setDefault( RimElementVectorResult::VectorView::AGGREGATED );
}
template <>
void AppEnum<RimElementVectorResult::VectorSurfaceCrossingLocation>::setUp()
{
addItem( RimElementVectorResult::VectorSurfaceCrossingLocation::VECTOR_ANCHOR, "VECTOR_ANCHOR", "At vector anchor" );
addItem( RimElementVectorResult::VectorSurfaceCrossingLocation::VECTOR_CENTER, "VECTOR_CENTER", "At vector center" );
setDefault( RimElementVectorResult::VectorSurfaceCrossingLocation::VECTOR_ANCHOR );
} }
} // namespace caf } // namespace caf
@ -65,15 +86,27 @@ RimElementVectorResult::RimElementVectorResult()
m_legendConfig = new RimRegularLegendConfig(); m_legendConfig = new RimRegularLegendConfig();
m_legendConfig.uiCapability()->setUiHidden( true ); m_legendConfig.uiCapability()->setUiHidden( true );
CAF_PDM_InitField( &m_resultName, "ResultVariable", QString( "Oil" ), "Value", "", "", "" ); CAF_PDM_InitField( &m_showOil, "ShowOil", true, "Oil", "", "", "" );
m_resultName.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() ); CAF_PDM_InitField( &m_showGas, "ShowGas", false, "Gas", "", "", "" );
m_resultName.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP ); CAF_PDM_InitField( &m_showWater, "ShowWater", true, "Water", "", "", "" );
CAF_PDM_InitField( &m_showResult, "ShowResult", false, "", "", "", "" ); CAF_PDM_InitField( &m_showResult, "ShowResult", false, "", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_vectorView, "VectorView", "View vectors", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_vectorSurfaceCrossingLocation,
"VectorSurfaceCrossingLocation",
"Vectors touching surface",
"",
"",
"" );
m_vectorSurfaceCrossingLocation.uiCapability()->setUiReadOnly( m_vectorView() ==
RimElementVectorResult::VectorView::AGGREGATED );
CAF_PDM_InitField( &m_showVectorI, "ShowVectorI", true, "I", "", "", "" ); CAF_PDM_InitField( &m_showVectorI, "ShowVectorI", true, "I", "", "", "" );
CAF_PDM_InitField( &m_showVectorJ, "ShowVectorJ", true, "J", "", "", "" ); CAF_PDM_InitField( &m_showVectorJ, "ShowVectorJ", true, "J", "", "", "" );
CAF_PDM_InitField( &m_showVectorK, "ShowVectorK", true, "K", "", "", "" ); CAF_PDM_InitField( &m_showVectorK, "ShowVectorK", true, "K", "", "", "" );
CAF_PDM_InitField( &m_showNncData, "ShowNncData", true, "Show NNC data", "", "", "" );
CAF_PDM_InitField( &m_threshold, "Threshold", 0.0f, "Threshold", "", "", "" ); CAF_PDM_InitField( &m_threshold, "Threshold", 0.0f, "Threshold", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_vectorColor, "VectorColor", "Color", "", "", "" ); CAF_PDM_InitFieldNoDefault( &m_vectorColor, "VectorColor", "Color", "", "", "" );
@ -111,6 +144,38 @@ bool RimElementVectorResult::showResult() const
return m_showResult(); return m_showResult();
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimElementVectorResult::VectorView RimElementVectorResult::vectorView() const
{
return m_vectorView();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimElementVectorResult::showOil() const
{
return m_showOil();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimElementVectorResult::showGas() const
{
return m_showGas();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimElementVectorResult::showWater() const
{
return m_showWater();
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -136,6 +201,22 @@ bool RimElementVectorResult::showVectorK() const
return m_showVectorK(); return m_showVectorK();
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimElementVectorResult::showNncData() const
{
return m_showNncData();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimElementVectorResult::VectorSurfaceCrossingLocation RimElementVectorResult::vectorSuraceCrossingLocation() const
{
return m_vectorSurfaceCrossingLocation();
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -181,30 +262,157 @@ const cvf::Color3f& RimElementVectorResult::getUniformVectorColor() const
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimElementVectorResult::mappingRange( double& min, double& max ) const void RimElementVectorResult::mappingRange( double& min, double& max ) const
{ {
min = cvf::UNDEFINED_DOUBLE; min = 0.0;
max = cvf::UNDEFINED_DOUBLE; max = 0.0;
Rim3dView* view = nullptr; Rim3dView* view = nullptr;
firstAncestorOrThisOfType( view ); firstAncestorOrThisOfType( view );
int currentTimeStep = view->currentTimeStep(); int currentTimeStep = view->currentTimeStep();
RigEclipseResultAddress resVarAddr = resultAddressCombined(); std::vector<RigEclipseResultAddress> resVarAddresses;
if ( !resVarAddr.isValid() ) return; size_t directions = 1;
if ( !resultAddressesIJK( resVarAddresses ) ) return;
std::vector<RigEclipseResultAddress> cleanedResVarAddresses;
directions = 0;
std::vector<cvf::Vec3d> unitVectors;
RimEclipseView* eclipseView = dynamic_cast<RimEclipseView*>( view ); for ( size_t fluidIndex = 0; fluidIndex < resVarAddresses.size(); fluidIndex += 3 )
RigCaseCellResultsData* resultsData =
eclipseView->eclipseCase()->eclipseCaseData()->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
resultsData->ensureKnownResultLoaded( resVarAddr );
if ( m_legendConfig->rangeMode() == RimRegularLegendConfig::RangeModeType::AUTOMATIC_ALLTIMESTEPS )
{ {
resultsData->minMaxCellScalarValues( resVarAddr, min, max ); if ( showVectorI() )
{
if ( fluidIndex == 0 )
{
directions++;
unitVectors.push_back( cvf::Vec3d( 1, 0, 0 ) );
}
cleanedResVarAddresses.push_back( resVarAddresses.at( 0 + fluidIndex ) );
}
if ( showVectorJ() )
{
if ( fluidIndex == 0 )
{
directions++;
unitVectors.push_back( cvf::Vec3d( 0, 1, 0 ) );
}
cleanedResVarAddresses.push_back( resVarAddresses.at( 1 + fluidIndex ) );
}
if ( showVectorK() )
{
if ( fluidIndex == 0 )
{
directions++;
unitVectors.push_back( cvf::Vec3d( 0, 0, 1 ) );
}
cleanedResVarAddresses.push_back( resVarAddresses.at( 2 + fluidIndex ) );
}
} }
else if ( m_legendConfig->rangeMode() == RimRegularLegendConfig::RangeModeType::AUTOMATIC_CURRENT_TIMESTEP ) resVarAddresses = cleanedResVarAddresses;
if ( directions > 0 )
{ {
resultsData->minMaxCellScalarValues( resVarAddr, currentTimeStep, min, max ); std::vector<double> directionsMax;
directionsMax.resize( directions, 0.0 );
std::vector<double> directionsMin;
directionsMin.resize( directions, 0.0 );
for ( size_t index = 0; index < resVarAddresses.size(); index += directions )
{
cvf::Vec3d aggregatedVectorMax;
cvf::Vec3d aggregatedVectorMin;
for ( size_t dir = 0; dir < directions; dir += 1 )
{
double localMin = cvf::UNDEFINED_DOUBLE;
double localMax = cvf::UNDEFINED_DOUBLE;
RigEclipseResultAddress resVarAddr = resVarAddresses.at( index + dir );
if ( !resVarAddr.isValid() ) return;
RimEclipseView* eclipseView = dynamic_cast<RimEclipseView*>( view );
RigCaseCellResultsData* resultsData =
eclipseView->eclipseCase()->eclipseCaseData()->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
resultsData->ensureKnownResultLoaded( resVarAddr );
if ( m_legendConfig->rangeMode() == RimRegularLegendConfig::RangeModeType::AUTOMATIC_ALLTIMESTEPS )
{
resultsData->minMaxCellScalarValues( resVarAddr, localMin, localMax );
}
else if ( m_legendConfig->rangeMode() == RimRegularLegendConfig::RangeModeType::AUTOMATIC_CURRENT_TIMESTEP )
{
resultsData->minMaxCellScalarValues( resVarAddr, currentTimeStep, localMin, localMax );
}
if ( vectorView() == RimElementVectorResult::VectorView::AGGREGATED )
{
aggregatedVectorMax += unitVectors.at( dir ) * localMax;
aggregatedVectorMin += unitVectors.at( dir ) * localMin;
}
else
{
directionsMax[dir] += localMax;
directionsMin[dir] += localMin;
}
}
if ( vectorView() == RimElementVectorResult::VectorView::AGGREGATED )
{
directionsMax[0] += aggregatedVectorMax.length();
directionsMin[0] += aggregatedVectorMin.length();
}
}
min = directionsMin.front();
max = directionsMax.front();
if ( vectorView() != RimElementVectorResult::VectorView::AGGREGATED )
{
for ( size_t i = 0; i < directionsMax.size(); i++ )
{
max = std::max<double>( max, directionsMax.at( i ) );
min = std::min<double>( min, directionsMin.at( i ) );
}
}
else
{
max = std::max<double>( max, min );
min = 0.0;
}
}
if ( showNncData() )
{
RigNNCData* nncData =
dynamic_cast<RimEclipseView*>( view )->eclipseCase()->eclipseCaseData()->mainGrid()->nncData();
std::vector<RigEclipseResultAddress> combinedAddresses;
if ( !resultAddressesCombined( combinedAddresses ) ) return;
for ( size_t flIdx = 0; flIdx < combinedAddresses.size(); flIdx++ )
{
if ( combinedAddresses[flIdx].m_resultCatType == RiaDefines::ResultCatType::DYNAMIC_NATIVE )
{
if ( m_legendConfig->rangeMode() == RimRegularLegendConfig::RangeModeType::AUTOMATIC_ALLTIMESTEPS )
{
const std::vector<std::vector<double>>* nncResultVals =
nncData->dynamicConnectionScalarResult( combinedAddresses[flIdx] );
for ( size_t i = 0; i < nncResultVals->size(); i++ )
{
for ( size_t j = 0; j < nncResultVals->at( i ).size(); j++ )
{
max = std::max<double>( max, nncResultVals->at( i ).at( j ) );
min = std::min<double>( min, nncResultVals->at( i ).at( j ) );
}
}
}
else if ( m_legendConfig->rangeMode() == RimRegularLegendConfig::RangeModeType::AUTOMATIC_CURRENT_TIMESTEP )
{
const std::vector<double>* nncResultVals =
nncData->dynamicConnectionScalarResult( combinedAddresses[flIdx],
static_cast<size_t>( currentTimeStep ) );
for ( size_t i = 0; i < nncResultVals->size(); i++ )
{
max = std::max<double>( max, nncResultVals->at( i ) );
min = std::min<double>( min, nncResultVals->at( i ) );
}
}
}
}
} }
} }
@ -214,13 +422,29 @@ void RimElementVectorResult::mappingRange( double& min, double& max ) const
void RimElementVectorResult::updateLegendRangesTextAndVisibility( RiuViewer* nativeOrOverrideViewer, void RimElementVectorResult::updateLegendRangesTextAndVisibility( RiuViewer* nativeOrOverrideViewer,
bool isUsingOverrideViewer ) bool isUsingOverrideViewer )
{ {
m_legendConfig->setTitle( QString( "Element Vector Result: \n" ) + resultName() ); QStringList resultNames;
if ( showOil() )
{
resultNames << QString( "Oil" );
}
if ( showGas() )
{
resultNames << QString( "Gas" );
}
if ( showWater() )
{
resultNames << QString( "Water" );
}
m_legendConfig->setTitle( QString( "Element Vector Result: \n" ) + resultNames.join( ", " ) );
double minResultValue; double minResultValue;
double maxResultValue; double maxResultValue;
mappingRange( minResultValue, maxResultValue ); mappingRange( minResultValue, maxResultValue );
m_legendConfig->setAutomaticRanges( minResultValue, maxResultValue, minResultValue, maxResultValue ); m_legendConfig->setAutomaticRanges( minResultValue, maxResultValue, minResultValue, maxResultValue );
m_legendConfig->setMappingMode( RimRegularLegendConfig::MappingType::LINEAR_CONTINUOUS );
double posClosestToZero = HUGE_VAL; double posClosestToZero = HUGE_VAL;
double negClosestToZero = -HUGE_VAL; double negClosestToZero = -HUGE_VAL;
m_legendConfig->setClosestToZeroValues( posClosestToZero, negClosestToZero, posClosestToZero, negClosestToZero ); m_legendConfig->setClosestToZeroValues( posClosestToZero, negClosestToZero, posClosestToZero, negClosestToZero );
@ -235,27 +459,6 @@ const RimRegularLegendConfig* RimElementVectorResult::legendConfig() const
return m_legendConfig(); return m_legendConfig();
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimElementVectorResult::resultName() const
{
return m_resultName();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::string> RimElementVectorResult::getResultMetaDataForUIFieldSetting()
{
std::vector<std::string> fieldNames;
fieldNames.push_back( "Oil" );
fieldNames.push_back( "Water" );
fieldNames.push_back( "Gas" );
return fieldNames;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -267,6 +470,11 @@ void RimElementVectorResult::fieldChangedByUi( const caf::PdmFieldHandle* change
{ {
setShowResult( m_showResult ); setShowResult( m_showResult );
} }
if ( changedField == &m_vectorView )
{
m_vectorSurfaceCrossingLocation.uiCapability()->setUiReadOnly( vectorView() ==
RimElementVectorResult::VectorView::AGGREGATED );
}
RimEclipseView* view; RimEclipseView* view;
firstAncestorOrThisOfType( view ); firstAncestorOrThisOfType( view );
@ -281,45 +489,28 @@ caf::PdmFieldHandle* RimElementVectorResult::objectToggleField()
return &m_showResult; return &m_showResult;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo>
RimElementVectorResult::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly )
{
QList<caf::PdmOptionItemInfo> options;
*useOptionsOnly = true;
if ( fieldNeedingOptions == &m_resultName )
{
std::vector<std::string> fieldCompNames = getResultMetaDataForUIFieldSetting();
for ( size_t oIdx = 0; oIdx < fieldCompNames.size(); ++oIdx )
{
options.push_back( caf::PdmOptionItemInfo( QString::fromStdString( fieldCompNames[oIdx] ),
QString::fromStdString( fieldCompNames[oIdx] ) ) );
}
}
return options;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimElementVectorResult::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) void RimElementVectorResult::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{ {
uiOrdering.add( &m_resultName ); caf::PdmUiGroup* fluidsGroup = uiOrdering.addNewGroup( "Fluids" );
fluidsGroup->add( &m_showOil );
fluidsGroup->add( &m_showGas );
fluidsGroup->add( &m_showWater );
caf::PdmUiGroup* visibilityGroup = uiOrdering.addNewGroup( "Visibility" ); caf::PdmUiGroup* visibilityGroup = uiOrdering.addNewGroup( "Visibility" );
visibilityGroup->add( &m_vectorView );
visibilityGroup->add( &m_vectorSurfaceCrossingLocation );
visibilityGroup->add( &m_showVectorI ); visibilityGroup->add( &m_showVectorI );
visibilityGroup->add( &m_showVectorJ ); visibilityGroup->add( &m_showVectorJ );
visibilityGroup->add( &m_showVectorK ); visibilityGroup->add( &m_showVectorK );
visibilityGroup->add( &m_showNncData );
visibilityGroup->add( &m_threshold ); visibilityGroup->add( &m_threshold );
caf::PdmUiGroup* vectorColorsGroup = uiOrdering.addNewGroup( "Vector Colors" ); caf::PdmUiGroup* vectorColorsGroup = uiOrdering.addNewGroup( "Vector Colors" );
vectorColorsGroup->add( &m_vectorColor ); vectorColorsGroup->add( &m_vectorColor );
if ( m_vectorColor == UNIFORM_COLOR ) if ( m_vectorColor == TensorColors::UNIFORM_COLOR )
{ {
vectorColorsGroup->add( &m_uniformVectorColor ); vectorColorsGroup->add( &m_uniformVectorColor );
} }
@ -334,75 +525,55 @@ void RimElementVectorResult::defineUiOrdering( QString uiConfigName, caf::PdmUiO
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimElementVectorResult::defineEditorAttribute( const caf::PdmFieldHandle* field, bool RimElementVectorResult::resultAddressesCombined( std::vector<RigEclipseResultAddress>& addresses ) const
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute )
{
if ( field == &m_resultName )
{
caf::PdmUiListEditorAttribute* listEditAttr = dynamic_cast<caf::PdmUiListEditorAttribute*>( attribute );
if ( listEditAttr )
{
listEditAttr->m_heightHint = 50;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigEclipseResultAddress RimElementVectorResult::resultAddressCombined() const
{
if ( resultName() == "Oil" )
{
return RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE,
RiaDefines::combinedOilFluxResultName() );
}
else if ( resultName() == "Gas" )
{
return RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE,
RiaDefines::combinedGasFluxResultName() );
}
else if ( resultName() == "Water" )
{
return RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE,
RiaDefines::combinedWaterFluxResultName() );
}
return RigEclipseResultAddress();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimElementVectorResult::resultAddressIJK( std::vector<RigEclipseResultAddress>& addresses ) const
{ {
addresses.clear(); addresses.clear();
// TODO: use enum?? if ( showOil() )
if ( resultName() == "Oil" ) {
addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE,
RiaDefines::combinedOilFluxResultName() ) );
}
if ( showGas() )
{
addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE,
RiaDefines::combinedGasFluxResultName() ) );
}
if ( showWater() )
{
addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE,
RiaDefines::combinedWaterFluxResultName() ) );
}
return addresses.size() > 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimElementVectorResult::resultAddressesIJK( std::vector<RigEclipseResultAddress>& addresses ) const
{
addresses.clear();
if ( showOil() )
{ {
addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILI+" ) ); addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILI+" ) );
addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILJ+" ) ); addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILJ+" ) );
addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILK+" ) ); addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILK+" ) );
return true;
} }
else if ( resultName() == "Gas" ) if ( showGas() )
{ {
addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASI+" ) ); addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASI+" ) );
addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASJ+" ) ); addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASJ+" ) );
addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASK+" ) ); addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASK+" ) );
return true;
} }
else if ( resultName() == "Water" ) if ( showWater() )
{ {
addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATI+" ) ); addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATI+" ) );
addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATJ+" ) ); addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATJ+" ) );
addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATK+" ) ); addresses.push_back( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATK+" ) );
return true;
} }
return false; return addresses.size() > 0;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -44,69 +44,85 @@ class RimElementVectorResult : public caf::PdmObject
CAF_PDM_HEADER_INIT; CAF_PDM_HEADER_INIT;
public: public:
enum TensorColors enum class TensorColors
{ {
UNIFORM_COLOR, UNIFORM_COLOR,
RESULT_COLORS RESULT_COLORS
}; };
enum ScaleMethod enum class ScaleMethod
{ {
RESULT, RESULT,
RESULT_LOG,
CONSTANT CONSTANT
}; };
enum class VectorView
{
AGGREGATED,
INDIVIDUAL
};
enum class VectorSurfaceCrossingLocation
{
VECTOR_ANCHOR,
VECTOR_CENTER
};
public: public:
RimElementVectorResult(); RimElementVectorResult();
~RimElementVectorResult() override; ~RimElementVectorResult() override;
void setShowResult( bool enableResult ); void setShowResult( bool enableResult );
bool showResult() const; bool showResult() const;
bool showVectorI() const; VectorView vectorView() const;
bool showVectorJ() const; bool showOil() const;
bool showVectorK() const; bool showGas() const;
float threshold() const; bool showWater() const;
float sizeScale() const; bool showVectorI() const;
TensorColors vectorColors() const; bool showVectorJ() const;
ScaleMethod scaleMethod() const; bool showVectorK() const;
bool showNncData() const;
VectorSurfaceCrossingLocation vectorSuraceCrossingLocation() const;
float threshold() const;
float sizeScale() const;
TensorColors vectorColors() const;
ScaleMethod scaleMethod() const;
const cvf::Color3f& getUniformVectorColor() const; const cvf::Color3f& getUniformVectorColor() const;
const RimRegularLegendConfig* legendConfig() const; const RimRegularLegendConfig* legendConfig() const;
void mappingRange( double& min, double& max ) const; void mappingRange( double& min, double& max ) const;
RigEclipseResultAddress resultAddressCombined() const; bool resultAddressesCombined( std::vector<RigEclipseResultAddress>& addresses ) const;
bool resultAddressIJK( std::vector<RigEclipseResultAddress>& addresses ) const; bool resultAddressesIJK( std::vector<RigEclipseResultAddress>& addresses ) const;
QString resultName() const;
void updateLegendRangesTextAndVisibility( RiuViewer* nativeOrOverrideViewer, bool isUsingOverrideViewer ); void updateLegendRangesTextAndVisibility( RiuViewer* nativeOrOverrideViewer, bool isUsingOverrideViewer );
private: private:
std::vector<std::string> getResultMetaDataForUIFieldSetting(); void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; caf::PdmFieldHandle* objectToggleField() override;
caf::PdmFieldHandle* objectToggleField() override; void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override; void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
static QString fieldNameFromUi( const QString& uiFieldName ); static QString fieldNameFromUi( const QString& uiFieldName );
private: private:
caf::PdmField<bool> m_showResult; caf::PdmField<bool> m_showResult;
caf::PdmField<QString> m_resultName; caf::PdmField<bool> m_showOil;
caf::PdmField<bool> m_showVectorI; caf::PdmField<bool> m_showGas;
caf::PdmField<bool> m_showVectorJ; caf::PdmField<bool> m_showWater;
caf::PdmField<bool> m_showVectorK; caf::PdmField<caf::AppEnum<VectorView>> m_vectorView;
caf::PdmField<float> m_threshold; caf::PdmField<bool> m_showVectorI;
caf::PdmField<caf::AppEnum<TensorColors>> m_vectorColor; caf::PdmField<bool> m_showVectorJ;
caf::PdmField<cvf::Color3f> m_uniformVectorColor; caf::PdmField<bool> m_showVectorK;
caf::PdmField<caf::AppEnum<ScaleMethod>> m_scaleMethod; caf::PdmField<bool> m_showNncData;
caf::PdmField<float> m_sizeScale; caf::PdmField<caf::AppEnum<VectorSurfaceCrossingLocation>> m_vectorSurfaceCrossingLocation;
caf::PdmField<RimRegularLegendConfig::RangeModeEnum> m_rangeMode; caf::PdmField<float> m_threshold;
caf::PdmChildField<RimRegularLegendConfig*> m_legendConfig; caf::PdmField<caf::AppEnum<TensorColors>> m_vectorColor;
caf::PdmField<cvf::Color3f> m_uniformVectorColor;
caf::PdmField<caf::AppEnum<ScaleMethod>> m_scaleMethod;
caf::PdmField<float> m_sizeScale;
caf::PdmField<RimRegularLegendConfig::RangeModeEnum> m_rangeMode;
caf::PdmChildField<RimRegularLegendConfig*> m_legendConfig;
}; };

View File

@ -36,6 +36,19 @@ cvf::Vec3d
return centerCoord; return centerCoord;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec3d GeometryTools::computeTriangleCenter( const cvf::Vec3d& v0, const cvf::Vec3d& v1, const cvf::Vec3d& v2 )
{
cvf::Vec3d centerCoord = v0;
centerCoord += v1;
centerCoord += v2;
centerCoord /= 3.0;
return centerCoord;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Ez = Plane normal, Ex = in XY plane (horizontal), Ey = semi vertical upwards /// Ez = Plane normal, Ex = in XY plane (horizontal), Ey = semi vertical upwards
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -36,6 +36,9 @@ class GeometryTools
public: public:
static cvf::Vec3d static cvf::Vec3d
computeFaceCenter( const cvf::Vec3d& v0, const cvf::Vec3d& v1, const cvf::Vec3d& v2, const cvf::Vec3d& v3 ); computeFaceCenter( const cvf::Vec3d& v0, const cvf::Vec3d& v1, const cvf::Vec3d& v2, const cvf::Vec3d& v3 );
static cvf::Vec3d computeTriangleCenter( const cvf::Vec3d& v0, const cvf::Vec3d& v1, const cvf::Vec3d& v2 );
template <typename Vec3Type>
static Vec3Type computePolygonCenter( const std::vector<Vec3Type>& polygon );
static cvf::Mat3f computePlaneHorizontalRotationMx( const cvf::Vec3f& inPlaneVec0, const cvf::Vec3f& inPlaneVec1 ); static cvf::Mat3f computePlaneHorizontalRotationMx( const cvf::Vec3f& inPlaneVec0, const cvf::Vec3f& inPlaneVec1 );
static cvf::Vec3d projectPointOnLine( const cvf::Vec3d& p1, static cvf::Vec3d projectPointOnLine( const cvf::Vec3d& p1,

View File

@ -21,6 +21,25 @@
namespace cvf namespace cvf
{ {
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
template <typename Vec3Type>
Vec3Type GeometryTools::computePolygonCenter(const std::vector<Vec3Type>& polygon)
{
Vec3Type s;
for (size_t i = 0; i < polygon.size(); i++)
{
s.x() += polygon[i].x();
s.y() += polygon[i].y();
s.z() += polygon[i].z();
}
s /= polygon.size();
return s;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------