diff --git a/ApplicationCode/ModelVisualization/Intersections/CMakeLists_files.cmake b/ApplicationCode/ModelVisualization/Intersections/CMakeLists_files.cmake index 1b0684cc7c..d3e0807856 100644 --- a/ApplicationCode/ModelVisualization/Intersections/CMakeLists_files.cmake +++ b/ApplicationCode/ModelVisualization/Intersections/CMakeLists_files.cmake @@ -3,6 +3,7 @@ set (SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RivIntersectionGeometryGenerator.h ${CMAKE_CURRENT_LIST_DIR}/RivIntersectionPartMgr.h ${CMAKE_CURRENT_LIST_DIR}/RivIntersectionSourceInfo.h +${CMAKE_CURRENT_LIST_DIR}/RivIntersectionResultsColoringTools.h ${CMAKE_CURRENT_LIST_DIR}/RivHexGridIntersectionTools.h ${CMAKE_CURRENT_LIST_DIR}/RivIntersectionBoxGeometryGenerator.h ${CMAKE_CURRENT_LIST_DIR}/RivIntersectionBoxPartMgr.h @@ -14,6 +15,7 @@ set (SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RivIntersectionGeometryGenerator.cpp ${CMAKE_CURRENT_LIST_DIR}/RivIntersectionPartMgr.cpp ${CMAKE_CURRENT_LIST_DIR}/RivIntersectionSourceInfo.cpp +${CMAKE_CURRENT_LIST_DIR}/RivIntersectionResultsColoringTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RivHexGridIntersectionTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RivIntersectionBoxGeometryGenerator.cpp ${CMAKE_CURRENT_LIST_DIR}/RivIntersectionBoxPartMgr.cpp diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxGeometryGenerator.h b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxGeometryGenerator.h index c26baeab46..0b23af9ff6 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxGeometryGenerator.h +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxGeometryGenerator.h @@ -37,7 +37,6 @@ class ScalarMapper; class DrawableGeo; } // namespace cvf - class RivIntersectionBoxGeometryGenerator : public cvf::Object, public RivIntersectionGeometryGeneratorIF { public: @@ -46,19 +45,20 @@ public: ~RivIntersectionBoxGeometryGenerator() override; - bool isAnyGeometryPresent() const override; - // Mapping between cells and geometry - const std::vector& triangleToCellIndex() const override; - const std::vector& triangleVxToCellCornerInterpolationWeights() const override; - const cvf::Vec3fArray* triangleVxes() const override; - // Generate geometry cvf::ref generateSurface(); cvf::ref createMeshDrawable(); - RimIntersectionBox* intersectionBox() const; + // GeomGen Interface + + bool isAnyGeometryPresent() const override; + + const std::vector& triangleToCellIndex() const override; + const std::vector& triangleVxToCellCornerInterpolationWeights() const override; + const cvf::Vec3fArray* triangleVxes() const override; + private: void calculateArrays(); diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp index ab5c70bdab..ffdc87d90f 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp @@ -38,6 +38,7 @@ #include "RivIntersectionBoxSourceInfo.h" #include "RivIntersectionPartMgr.h" +#include "RivIntersectionResultsColoringTools.h" #include "RivMeshLinesSourceInfo.h" #include "RivPartPriority.h" #include "RivResultToTextureMapper.h" @@ -90,267 +91,6 @@ void RivIntersectionBoxPartMgr::updateCellResultColor( size_t timeStepIndex ) m_intersectionBoxFacesTextureCoords.p() ); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivIntersectionResultsColoringTools::updateCellResultColorStatic( - size_t timeStepIndex, - RimIntersectionHandle* rimIntersectionHandle, - const RivIntersectionGeometryGeneratorIF* intersectionGeomGenIF, - cvf::Part* intersectionFacesPart, - cvf::Vec2fArray* intersectionFacesTextureCoords ) -{ - if ( !intersectionGeomGenIF->isAnyGeometryPresent() ) return; - - RimGridView* gridView = nullptr; - rimIntersectionHandle->firstAncestorOrThisOfType( gridView ); - - if ( !gridView ) return; - - bool isLightingDisabled = gridView->isLightingDisabled(); - - RimEclipseResultDefinition* eclipseResDef = nullptr; - RimGeoMechResultDefinition* geomResultDef = nullptr; - const cvf::ScalarMapper* scalarColorMapper = nullptr; - const RivTernaryScalarMapper* ternaryColorMapper = nullptr; - - // Separate intersection result - - RimIntersectionResultDefinition* sepResDef = rimIntersectionHandle->activeSeparateResultDefinition(); - if ( sepResDef && sepResDef->activeCase() ) - { - if ( sepResDef->isEclipseResultDefinition() ) - { - eclipseResDef = sepResDef->eclipseResultDefinition(); - } - else - { - geomResultDef = sepResDef->geoMechResultDefinition(); - } - - scalarColorMapper = sepResDef->regularLegendConfig()->scalarMapper(); - ternaryColorMapper = sepResDef->ternaryLegendConfig()->scalarMapper(); - timeStepIndex = sepResDef->timeStep(); - } - - // Ordinary result - - if ( !eclipseResDef && !geomResultDef ) - { - RimEclipseView* eclipseView = nullptr; - rimIntersectionHandle->firstAncestorOrThisOfType( eclipseView ); - - if ( eclipseView ) - { - eclipseResDef = eclipseView->cellResult(); - scalarColorMapper = eclipseView->cellResult()->legendConfig()->scalarMapper(); - ternaryColorMapper = eclipseView->cellResult()->ternaryLegendConfig()->scalarMapper(); - timeStepIndex = eclipseView->currentTimeStep(); - } - - RimGeoMechView* geoView; - rimIntersectionHandle->firstAncestorOrThisOfType( geoView ); - - if ( geoView ) - { - geomResultDef = geoView->cellResult(); - scalarColorMapper = geoView->cellResult()->legendConfig()->scalarMapper(); - timeStepIndex = geoView->currentTimeStep(); - } - } - - if ( eclipseResDef ) - { - if ( eclipseResDef->isTernarySaturationSelected() ) - { - RivIntersectionResultsColoringTools::updateEclipseTernaryCellResultColors( eclipseResDef, - ternaryColorMapper, - timeStepIndex, - isLightingDisabled, - intersectionGeomGenIF - ->triangleToCellIndex(), - intersectionFacesPart, - intersectionFacesTextureCoords ); - } - else - { - RivIntersectionResultsColoringTools::updateEclipseCellResultColors( eclipseResDef, - scalarColorMapper, - timeStepIndex, - isLightingDisabled, - intersectionGeomGenIF->triangleToCellIndex(), - intersectionFacesPart, - intersectionFacesTextureCoords ); - } - } - else if ( geomResultDef ) - { - RivIntersectionResultsColoringTools::updateGeoMechCellResultColors( geomResultDef, - timeStepIndex, - scalarColorMapper, - isLightingDisabled, - intersectionGeomGenIF, - intersectionFacesPart, - intersectionFacesTextureCoords ); - return; - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivIntersectionResultsColoringTools::updateEclipseCellResultColors( - const RimEclipseResultDefinition* eclipseResDef, - const cvf::ScalarMapper* scalarColorMapper, - size_t timeStepIndex, - bool isLightingDisabled, - const std::vector& triangleToCellIndexMapping, - cvf::Part* intersectionFacesPart, - cvf::Vec2fArray* intersectionFacesTextureCoords ) -{ - RigEclipseCaseData* eclipseCaseData = eclipseResDef->eclipseCase()->eclipseCaseData(); - - cvf::ref resultAccessor; - - if ( RiaDefines::isPerCellFaceResult( eclipseResDef->resultVariable() ) ) - { - resultAccessor = new RigHugeValResultAccessor; - } - else - { - resultAccessor = RigResultAccessorFactory::createFromResultDefinition( eclipseCaseData, - 0, - timeStepIndex, - eclipseResDef ); - } - - RivIntersectionResultsColoringTools::calculateEclipseTextureCoordinates( intersectionFacesTextureCoords, - triangleToCellIndexMapping, - resultAccessor.p(), - scalarColorMapper ); - - RivScalarMapperUtils::applyTextureResultsToPart( intersectionFacesPart, - intersectionFacesTextureCoords, - scalarColorMapper, - 1.0, - caf::FC_NONE, - isLightingDisabled ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivIntersectionResultsColoringTools::updateEclipseTernaryCellResultColors( - const RimEclipseResultDefinition* eclipseResDef, - const RivTernaryScalarMapper* ternaryColorMapper, - size_t timeStepIndex, - bool isLightingDisabled, - const std::vector& triangleToCellIndexMapping, - cvf::Part* intersectionFacesPart, - cvf::Vec2fArray* intersectionFacesTextureCoords ) -{ - RivTernaryTextureCoordsCreator texturer( eclipseResDef, ternaryColorMapper, timeStepIndex ); - - texturer.createTextureCoords( intersectionFacesTextureCoords, triangleToCellIndexMapping ); - - RivScalarMapperUtils::applyTernaryTextureResultsToPart( intersectionFacesPart, - intersectionFacesTextureCoords, - ternaryColorMapper, - 1.0, - caf::FC_NONE, - isLightingDisabled ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivIntersectionResultsColoringTools::updateGeoMechCellResultColors( - const RimGeoMechResultDefinition* geomResultDef, - size_t timeStepIndex, - const cvf::ScalarMapper* scalarColorMapper, - bool isLightingDisabled, - const RivIntersectionGeometryGeneratorIF* geomGenerator, - cvf::Part* intersectionFacesPart, - cvf::Vec2fArray* intersectionFacesTextureCoords ) -{ - RigGeoMechCaseData* caseData = nullptr; - RigFemResultAddress resVarAddress; - { - caseData = geomResultDef->ownerCaseData(); - resVarAddress = geomResultDef->resultAddress(); - } - - if ( !caseData ) return; - - const std::vector& triangleToCellIdx = geomGenerator->triangleToCellIndex(); - const cvf::Vec3fArray* triangelVxes = geomGenerator->triangleVxes(); - const std::vector& vertexWeights = - geomGenerator->triangleVxToCellCornerInterpolationWeights(); - - if ( resVarAddress.resultPosType == RIG_ELEMENT ) - { - const std::vector& resultValues = caseData->femPartResults()->resultValues( resVarAddress, - 0, - (int)timeStepIndex ); - - RivIntersectionResultsColoringTools::calculateElementBasedGeoMechTextureCoords( intersectionFacesTextureCoords, - resultValues, - triangleToCellIdx, - scalarColorMapper ); - } - else if ( resVarAddress.resultPosType == RIG_ELEMENT_NODAL_FACE ) - { - // Special direction sensitive result calculation - - if ( resVarAddress.componentName == "Pazi" || resVarAddress.componentName == "Pinc" ) - { - RivIntersectionResultsColoringTools::calculatePlaneAngleTextureCoords( intersectionFacesTextureCoords, - triangelVxes, - resVarAddress, - scalarColorMapper ); - } - else - { - RivIntersectionResultsColoringTools::calculateGeoMechTensorXfTextureCoords( intersectionFacesTextureCoords, - triangelVxes, - vertexWeights, - caseData, - resVarAddress, - (int)timeStepIndex, - scalarColorMapper ); - } - } - else - { - // Do a "Hack" to show elm nodal and not nodal POR results - - if ( resVarAddress.resultPosType == RIG_NODAL && resVarAddress.fieldName == "POR-Bar" ) - { - resVarAddress.resultPosType = RIG_ELEMENT_NODAL; - } - - const std::vector& resultValues = caseData->femPartResults()->resultValues( resVarAddress, - 0, - (int)timeStepIndex ); - - RigFemPart* femPart = caseData->femParts()->part( 0 ); - bool isElementNodalResult = !( resVarAddress.resultPosType == RIG_NODAL ); - - RivIntersectionResultsColoringTools::calculateNodeOrElementNodeBasedGeoMechTextureCoords( intersectionFacesTextureCoords, - vertexWeights, - resultValues, - isElementNodalResult, - femPart, - scalarColorMapper ); - } - - RivScalarMapperUtils::applyTextureResultsToPart( intersectionFacesPart, - intersectionFacesTextureCoords, - scalarColorMapper, - 1.0, - caf::FC_NONE, - isLightingDisabled ); -} //-------------------------------------------------------------------------------------------------- /// diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionGeometryGenerator.h b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionGeometryGenerator.h index b5fa0287df..15564dc3b8 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionGeometryGenerator.h +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionGeometryGenerator.h @@ -58,8 +58,6 @@ public: ~RivIntersectionGeometryGenerator() override; - bool isAnyGeometryPresent() const; - // Generate geometry cvf::ref generateSurface(); cvf::ref createMeshDrawable(); @@ -79,24 +77,22 @@ public: return m_faultMeshLabelAndAnchorPositions; } - // Mapping between cells and geometry - const std::vector& triangleToCellIndex() const; - const std::vector& triangleVxToCellCornerInterpolationWeights() const; - const cvf::Vec3fArray* triangleVxes() const; - RimIntersection* crossSection() const; cvf::Mat4d unflattenTransformMatrix( const cvf::Vec3d& intersectionPointFlat ); + // GeomGen Interface + bool isAnyGeometryPresent() const override; + + const std::vector& triangleToCellIndex() const override; + const std::vector& triangleVxToCellCornerInterpolationWeights() const override; + const cvf::Vec3fArray* triangleVxes() const override; + private: void calculateArrays(); void calculateSegementTransformPrLinePoint(); void calculateFlattenedOrOffsetedPolyline(); - // static size_t indexToNextValidPoint(const std::vector& polyLine, - // const cvf::Vec3d extrDir, - // size_t idxToStartOfLineSegment); - RimIntersection* m_crossSection; cvf::cref m_hexGrid; const std::vector> m_polyLines; diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp index f7efa84930..64f645ef94 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp @@ -51,6 +51,7 @@ #include "RivHexGridIntersectionTools.h" #include "RivIntersectionGeometryGenerator.h" +#include "RivIntersectionResultsColoringTools.h" #include "RivIntersectionSourceInfo.h" #include "RivMeshLinesSourceInfo.h" #include "RivObjectSourceInfo.h" @@ -214,171 +215,6 @@ void RivIntersectionResultsColoringTools::calculateNodeOrElementNodeBasedGeoMech } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivIntersectionResultsColoringTools::calculateElementBasedGeoMechTextureCoords( - cvf::Vec2fArray* textureCoords, - const std::vector& resultValues, - const std::vector& triangleToCellIdx, - const cvf::ScalarMapper* mapper ) -{ - textureCoords->resize( triangleToCellIdx.size() * 3 ); - - if ( resultValues.size() == 0 ) - { - textureCoords->setAll( cvf::Vec2f( 0.0, 1.0f ) ); - } - else - { - cvf::Vec2f* rawPtr = textureCoords->ptr(); - - for ( size_t triangleIdx = 0; triangleIdx < triangleToCellIdx.size(); triangleIdx++ ) - { - size_t resIdx = triangleToCellIdx[triangleIdx]; - float resValue = resultValues[resIdx]; - - size_t triangleVxIdx = triangleIdx * 3; - - if ( resValue == HUGE_VAL || resValue != resValue ) // a != a is true for NAN's - { - rawPtr[triangleVxIdx][1] = 1.0f; - rawPtr[triangleVxIdx + 1][1] = 1.0f; - rawPtr[triangleVxIdx + 2][1] = 1.0f; - } - else - { - rawPtr[triangleVxIdx] = mapper->mapToTextureCoord( resValue ); - rawPtr[triangleVxIdx + 1] = mapper->mapToTextureCoord( resValue ); - rawPtr[triangleVxIdx + 2] = mapper->mapToTextureCoord( resValue ); - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivIntersectionResultsColoringTools::calculateGeoMechTensorXfTextureCoords( - cvf::Vec2fArray* textureCoords, - const cvf::Vec3fArray* triangelVertices, - const std::vector& vertexWeights, - RigGeoMechCaseData* caseData, - const RigFemResultAddress& resVarAddress, - int timeStepIdx, - const cvf::ScalarMapper* mapper ) -{ - RiuGeoMechXfTensorResultAccessor accessor( caseData->femPartResults(), resVarAddress, timeStepIdx ); - - textureCoords->resize( vertexWeights.size() ); - cvf::Vec2f* rawPtr = textureCoords->ptr(); - int vxCount = static_cast( vertexWeights.size() ); - int triCount = vxCount / 3; - -#pragma omp parallel for schedule( dynamic ) - for ( int triangleIdx = 0; triangleIdx < triCount; ++triangleIdx ) - { - int triangleVxStartIdx = triangleIdx * 3; - float values[3]; - - accessor.calculateInterpolatedValue( &( ( *triangelVertices )[triangleVxStartIdx] ), - &( vertexWeights[triangleVxStartIdx] ), - values ); - - rawPtr[triangleVxStartIdx + 0] = ( values[0] != std::numeric_limits::infinity() ) - ? mapper->mapToTextureCoord( values[0] ) - : cvf::Vec2f( 0.0f, 1.0f ); - rawPtr[triangleVxStartIdx + 1] = ( values[1] != std::numeric_limits::infinity() ) - ? mapper->mapToTextureCoord( values[1] ) - : cvf::Vec2f( 0.0f, 1.0f ); - rawPtr[triangleVxStartIdx + 2] = ( values[2] != std::numeric_limits::infinity() ) - ? mapper->mapToTextureCoord( values[2] ) - : cvf::Vec2f( 0.0f, 1.0f ); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivIntersectionResultsColoringTools::calculatePlaneAngleTextureCoords( cvf::Vec2fArray* textureCoords, - const cvf::Vec3fArray* triangelVertices, - const RigFemResultAddress& resVarAddress, - const cvf::ScalarMapper* mapper ) -{ - textureCoords->resize( triangelVertices->size() ); - cvf::Vec2f* rawPtr = textureCoords->ptr(); - int vxCount = static_cast( triangelVertices->size() ); - int triCount = vxCount / 3; - - std::function operation; - if ( resVarAddress.componentName == "Pazi" ) - { - operation = []( const RiaOffshoreSphericalCoords& sphCoord ) { return (float)sphCoord.azi(); }; - } - else if ( resVarAddress.componentName == "Pinc" ) - { - operation = []( const RiaOffshoreSphericalCoords& sphCoord ) { return (float)sphCoord.inc(); }; - } - -#pragma omp parallel for schedule( dynamic ) - for ( int triangleIdx = 0; triangleIdx < triCount; ++triangleIdx ) - { - int triangleVxStartIdx = triangleIdx * 3; - - const cvf::Vec3f* triangle = &( ( *triangelVertices )[triangleVxStartIdx] ); - cvf::Mat3f rotMx = cvf::GeometryTools::computePlaneHorizontalRotationMx( triangle[1] - triangle[0], - triangle[2] - triangle[0] ); - - RiaOffshoreSphericalCoords sphCoord( - cvf::Vec3f( rotMx.rowCol( 0, 2 ), - rotMx.rowCol( 1, 2 ), - rotMx.rowCol( 2, 2 ) ) ); // Use Ez from the matrix as plane normal - - float angle = cvf::Math::toDegrees( operation( sphCoord ) ); - cvf::Vec2f texCoord = ( angle != std::numeric_limits::infinity() ) ? mapper->mapToTextureCoord( angle ) - : cvf::Vec2f( 0.0f, 1.0f ); - rawPtr[triangleVxStartIdx + 0] = texCoord; - rawPtr[triangleVxStartIdx + 1] = texCoord; - rawPtr[triangleVxStartIdx + 2] = texCoord; - } -} - -//-------------------------------------------------------------------------------------------------- -/// Calculates the texture coordinates in a "nearly" one dimensional texture. -/// Undefined values are coded with a y-texturecoordinate value of 1.0 instead of the normal 0.5 -//-------------------------------------------------------------------------------------------------- -void RivIntersectionResultsColoringTools::calculateEclipseTextureCoordinates( cvf::Vec2fArray* textureCoords, - const std::vector& triangleToCellIdxMap, - const RigResultAccessor* resultAccessor, - const cvf::ScalarMapper* mapper ) -{ - if ( !resultAccessor ) return; - - size_t numVertices = triangleToCellIdxMap.size() * 3; - - textureCoords->resize( numVertices ); - cvf::Vec2f* rawPtr = textureCoords->ptr(); - - int triangleCount = static_cast( triangleToCellIdxMap.size() ); - -#pragma omp parallel for - for ( int tIdx = 0; tIdx < triangleCount; tIdx++ ) - { - double cellScalarValue = resultAccessor->cellScalarGlobIdx( triangleToCellIdxMap[tIdx] ); - cvf::Vec2f texCoord = mapper->mapToTextureCoord( cellScalarValue ); - if ( cellScalarValue == HUGE_VAL || cellScalarValue != cellScalarValue ) // a != a is true for NAN's - { - texCoord[1] = 1.0f; - } - - size_t j; - for ( j = 0; j < 3; j++ ) - { - rawPtr[tIdx * 3 + j] = texCoord; - } - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.h b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.h index 12ba1beed6..52ded7c180 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.h +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.h @@ -114,73 +114,3 @@ private: bool m_isFlattened; }; -class RimIntersectionHandle; -class RivIntersectionGeometryGeneratorIF; -class RimEclipseResultDefinition; -class RimGeoMechResultDefinition; - -class RivIntersectionResultsColoringTools -{ -public: - static void updateCellResultColorStatic( size_t timeStepIndex, - RimIntersectionHandle* m_rimIntersectionBox, - const RivIntersectionGeometryGeneratorIF* m_intersectionBoxGenerator, - cvf::Part* m_intersectionBoxFaces, - cvf::Vec2fArray* m_intersectionBoxFacesTextureCoords ); - -private: - static void updateEclipseCellResultColors( const RimEclipseResultDefinition* eclipseResDef, - const cvf::ScalarMapper* scalarColorMapper, - size_t timeStepIndex, - bool isLightingDisabled, - const std::vector& triangleToCellIndexMapping, - cvf::Part* m_intersectionBoxFaces, - cvf::Vec2fArray* m_intersectionBoxFacesTextureCoords ); - - static void updateEclipseTernaryCellResultColors( const RimEclipseResultDefinition* eclipseResDef, - const RivTernaryScalarMapper* ternaryColorMapper, - size_t timeStepIndex, - bool isLightingDisabled, - const std::vector& triangleToCellIndexMapping, - cvf::Part* m_intersectionBoxFaces, - cvf::Vec2fArray* m_intersectionBoxFacesTextureCoords ); - - static void updateGeoMechCellResultColors( const RimGeoMechResultDefinition* geomResultDef, - size_t timeStepIndex, - const cvf::ScalarMapper* scalarColorMapper, - bool isLightingDisabled, - const RivIntersectionGeometryGeneratorIF* geomGenerator, - cvf::Part* m_intersectionBoxFaces, - cvf::Vec2fArray* m_intersectionBoxFacesTextureCoords ); - - static void calculateEclipseTextureCoordinates( cvf::Vec2fArray* textureCoords, - const std::vector& triangleToCellIdxMap, - const RigResultAccessor* resultAccessor, - const cvf::ScalarMapper* mapper ); - - static void calculateNodeOrElementNodeBasedGeoMechTextureCoords( - cvf::Vec2fArray* textureCoords, - const std::vector& vertexWeights, - const std::vector& resultValues, - bool isElementNodalResult, - const RigFemPart* femPart, - const cvf::ScalarMapper* mapper ); - - static void calculateElementBasedGeoMechTextureCoords( cvf::Vec2fArray* textureCoords, - const std::vector& resultValues, - const std::vector& triangleToCellIdx, - const cvf::ScalarMapper* mapper ); - - static void calculateGeoMechTensorXfTextureCoords( cvf::Vec2fArray* textureCoords, - const cvf::Vec3fArray* triangelVertices, - const std::vector& vertexWeights, - RigGeoMechCaseData* caseData, - const RigFemResultAddress& resVarAddress, - int timeStepIdx, - const cvf::ScalarMapper* mapper ); - - static void calculatePlaneAngleTextureCoords( cvf::Vec2fArray* textureCoords, - const cvf::Vec3fArray* triangelVertices, - const RigFemResultAddress& resVarAddress, - const cvf::ScalarMapper* mapper ); -}; \ No newline at end of file diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionResultsColoringTools.cpp b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionResultsColoringTools.cpp new file mode 100644 index 0000000000..b115478cea --- /dev/null +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionResultsColoringTools.cpp @@ -0,0 +1,473 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2019- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RivIntersectionResultsColoringTools.h" + +#include "RiuGeoMechXfTensorResultAccessor.h" + +#include "RimEclipseCase.h" +#include "RimEclipseCellColors.h" +#include "RimEclipseView.h" +#include "RimGeoMechCellColors.h" +#include "RimGeoMechView.h" +#include "RimGridView.h" +#include "RimIntersectionHandle.h" +#include "RimIntersectionResultDefinition.h" +#include "RimRegularLegendConfig.h" +#include "RimTernaryLegendConfig.h" + +#include "RigFemPartCollection.h" +#include "RigFemPartResultsCollection.h" +#include "RigFemResultAddress.h" +#include "RigGeoMechCaseData.h" +#include "RigResultAccessorFactory.h" + +#include "RivScalarMapperUtils.h" +#include "RivTernaryTextureCoordsCreator.h" + +#include "RiaOffshoreSphericalCoords.h" + +#include "cvfGeometryTools.h" +#include "cvfStructGridGeometryGenerator.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivIntersectionResultsColoringTools::updateCellResultColorStatic( + size_t timeStepIndex, + RimIntersectionHandle* rimIntersectionHandle, + const RivIntersectionGeometryGeneratorIF* intersectionGeomGenIF, + cvf::Part* intersectionFacesPart, + cvf::Vec2fArray* intersectionFacesTextureCoords ) +{ + if ( !intersectionGeomGenIF->isAnyGeometryPresent() ) return; + + RimGridView* gridView = nullptr; + rimIntersectionHandle->firstAncestorOrThisOfType( gridView ); + + if ( !gridView ) return; + + bool isLightingDisabled = gridView->isLightingDisabled(); + + RimEclipseResultDefinition* eclipseResDef = nullptr; + RimGeoMechResultDefinition* geomResultDef = nullptr; + const cvf::ScalarMapper* scalarColorMapper = nullptr; + const RivTernaryScalarMapper* ternaryColorMapper = nullptr; + + // Separate intersection result + + RimIntersectionResultDefinition* sepResDef = rimIntersectionHandle->activeSeparateResultDefinition(); + if ( sepResDef && sepResDef->activeCase() ) + { + if ( sepResDef->isEclipseResultDefinition() ) + { + eclipseResDef = sepResDef->eclipseResultDefinition(); + } + else + { + geomResultDef = sepResDef->geoMechResultDefinition(); + } + + scalarColorMapper = sepResDef->regularLegendConfig()->scalarMapper(); + ternaryColorMapper = sepResDef->ternaryLegendConfig()->scalarMapper(); + timeStepIndex = sepResDef->timeStep(); + } + + // Ordinary result + + if ( !eclipseResDef && !geomResultDef ) + { + RimEclipseView* eclipseView = nullptr; + rimIntersectionHandle->firstAncestorOrThisOfType( eclipseView ); + + if ( eclipseView ) + { + eclipseResDef = eclipseView->cellResult(); + scalarColorMapper = eclipseView->cellResult()->legendConfig()->scalarMapper(); + ternaryColorMapper = eclipseView->cellResult()->ternaryLegendConfig()->scalarMapper(); + timeStepIndex = eclipseView->currentTimeStep(); + } + + RimGeoMechView* geoView; + rimIntersectionHandle->firstAncestorOrThisOfType( geoView ); + + if ( geoView ) + { + geomResultDef = geoView->cellResult(); + scalarColorMapper = geoView->cellResult()->legendConfig()->scalarMapper(); + timeStepIndex = geoView->currentTimeStep(); + } + } + + if ( eclipseResDef ) + { + if ( eclipseResDef->isTernarySaturationSelected() ) + { + RivIntersectionResultsColoringTools::updateEclipseTernaryCellResultColors( eclipseResDef, + ternaryColorMapper, + timeStepIndex, + isLightingDisabled, + intersectionGeomGenIF + ->triangleToCellIndex(), + intersectionFacesPart, + intersectionFacesTextureCoords ); + } + else + { + RivIntersectionResultsColoringTools::updateEclipseCellResultColors( eclipseResDef, + scalarColorMapper, + timeStepIndex, + isLightingDisabled, + intersectionGeomGenIF->triangleToCellIndex(), + intersectionFacesPart, + intersectionFacesTextureCoords ); + } + } + else if ( geomResultDef ) + { + RivIntersectionResultsColoringTools::updateGeoMechCellResultColors( geomResultDef, + timeStepIndex, + scalarColorMapper, + isLightingDisabled, + intersectionGeomGenIF, + intersectionFacesPart, + intersectionFacesTextureCoords ); + return; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivIntersectionResultsColoringTools::updateEclipseCellResultColors( + const RimEclipseResultDefinition* eclipseResDef, + const cvf::ScalarMapper* scalarColorMapper, + size_t timeStepIndex, + bool isLightingDisabled, + const std::vector& triangleToCellIndexMapping, + cvf::Part* intersectionFacesPart, + cvf::Vec2fArray* intersectionFacesTextureCoords ) +{ + RigEclipseCaseData* eclipseCaseData = eclipseResDef->eclipseCase()->eclipseCaseData(); + + cvf::ref resultAccessor; + + if ( RiaDefines::isPerCellFaceResult( eclipseResDef->resultVariable() ) ) + { + resultAccessor = new RigHugeValResultAccessor; + } + else + { + resultAccessor = RigResultAccessorFactory::createFromResultDefinition( eclipseCaseData, + 0, + timeStepIndex, + eclipseResDef ); + } + + RivIntersectionResultsColoringTools::calculateEclipseTextureCoordinates( intersectionFacesTextureCoords, + triangleToCellIndexMapping, + resultAccessor.p(), + scalarColorMapper ); + + RivScalarMapperUtils::applyTextureResultsToPart( intersectionFacesPart, + intersectionFacesTextureCoords, + scalarColorMapper, + 1.0, + caf::FC_NONE, + isLightingDisabled ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivIntersectionResultsColoringTools::updateEclipseTernaryCellResultColors( + const RimEclipseResultDefinition* eclipseResDef, + const RivTernaryScalarMapper* ternaryColorMapper, + size_t timeStepIndex, + bool isLightingDisabled, + const std::vector& triangleToCellIndexMapping, + cvf::Part* intersectionFacesPart, + cvf::Vec2fArray* intersectionFacesTextureCoords ) +{ + RivTernaryTextureCoordsCreator texturer( eclipseResDef, ternaryColorMapper, timeStepIndex ); + + texturer.createTextureCoords( intersectionFacesTextureCoords, triangleToCellIndexMapping ); + + RivScalarMapperUtils::applyTernaryTextureResultsToPart( intersectionFacesPart, + intersectionFacesTextureCoords, + ternaryColorMapper, + 1.0, + caf::FC_NONE, + isLightingDisabled ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivIntersectionResultsColoringTools::updateGeoMechCellResultColors( + const RimGeoMechResultDefinition* geomResultDef, + size_t timeStepIndex, + const cvf::ScalarMapper* scalarColorMapper, + bool isLightingDisabled, + const RivIntersectionGeometryGeneratorIF* geomGenerator, + cvf::Part* intersectionFacesPart, + cvf::Vec2fArray* intersectionFacesTextureCoords ) +{ + RigGeoMechCaseData* caseData = nullptr; + RigFemResultAddress resVarAddress; + { + caseData = geomResultDef->ownerCaseData(); + resVarAddress = geomResultDef->resultAddress(); + } + + if ( !caseData ) return; + + const std::vector& triangleToCellIdx = geomGenerator->triangleToCellIndex(); + const cvf::Vec3fArray* triangelVxes = geomGenerator->triangleVxes(); + const std::vector& vertexWeights = + geomGenerator->triangleVxToCellCornerInterpolationWeights(); + + if ( resVarAddress.resultPosType == RIG_ELEMENT ) + { + const std::vector& resultValues = caseData->femPartResults()->resultValues( resVarAddress, + 0, + (int)timeStepIndex ); + + RivIntersectionResultsColoringTools::calculateElementBasedGeoMechTextureCoords( intersectionFacesTextureCoords, + resultValues, + triangleToCellIdx, + scalarColorMapper ); + } + else if ( resVarAddress.resultPosType == RIG_ELEMENT_NODAL_FACE ) + { + // Special direction sensitive result calculation + + if ( resVarAddress.componentName == "Pazi" || resVarAddress.componentName == "Pinc" ) + { + RivIntersectionResultsColoringTools::calculatePlaneAngleTextureCoords( intersectionFacesTextureCoords, + triangelVxes, + resVarAddress, + scalarColorMapper ); + } + else + { + RivIntersectionResultsColoringTools::calculateGeoMechTensorXfTextureCoords( intersectionFacesTextureCoords, + triangelVxes, + vertexWeights, + caseData, + resVarAddress, + (int)timeStepIndex, + scalarColorMapper ); + } + } + else + { + // Do a "Hack" to show elm nodal and not nodal POR results + + if ( resVarAddress.resultPosType == RIG_NODAL && resVarAddress.fieldName == "POR-Bar" ) + { + resVarAddress.resultPosType = RIG_ELEMENT_NODAL; + } + + const std::vector& resultValues = caseData->femPartResults()->resultValues( resVarAddress, + 0, + (int)timeStepIndex ); + + RigFemPart* femPart = caseData->femParts()->part( 0 ); + bool isElementNodalResult = !( resVarAddress.resultPosType == RIG_NODAL ); + + RivIntersectionResultsColoringTools::calculateNodeOrElementNodeBasedGeoMechTextureCoords( intersectionFacesTextureCoords, + vertexWeights, + resultValues, + isElementNodalResult, + femPart, + scalarColorMapper ); + } + + RivScalarMapperUtils::applyTextureResultsToPart( intersectionFacesPart, + intersectionFacesTextureCoords, + scalarColorMapper, + 1.0, + caf::FC_NONE, + isLightingDisabled ); +} + +//-------------------------------------------------------------------------------------------------- +/// Calculates the texture coordinates in a "nearly" one dimensional texture. +/// Undefined values are coded with a y-texturecoordinate value of 1.0 instead of the normal 0.5 +//-------------------------------------------------------------------------------------------------- +void RivIntersectionResultsColoringTools::calculateEclipseTextureCoordinates( cvf::Vec2fArray* textureCoords, + const std::vector& triangleToCellIdxMap, + const RigResultAccessor* resultAccessor, + const cvf::ScalarMapper* mapper ) +{ + if ( !resultAccessor ) return; + + size_t numVertices = triangleToCellIdxMap.size() * 3; + + textureCoords->resize( numVertices ); + cvf::Vec2f* rawPtr = textureCoords->ptr(); + + int triangleCount = static_cast( triangleToCellIdxMap.size() ); + +#pragma omp parallel for + for ( int tIdx = 0; tIdx < triangleCount; tIdx++ ) + { + double cellScalarValue = resultAccessor->cellScalarGlobIdx( triangleToCellIdxMap[tIdx] ); + cvf::Vec2f texCoord = mapper->mapToTextureCoord( cellScalarValue ); + if ( cellScalarValue == HUGE_VAL || cellScalarValue != cellScalarValue ) // a != a is true for NAN's + { + texCoord[1] = 1.0f; + } + + size_t j; + for ( j = 0; j < 3; j++ ) + { + rawPtr[tIdx * 3 + j] = texCoord; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivIntersectionResultsColoringTools::calculateElementBasedGeoMechTextureCoords( + cvf::Vec2fArray* textureCoords, + const std::vector& resultValues, + const std::vector& triangleToCellIdx, + const cvf::ScalarMapper* mapper ) +{ + textureCoords->resize( triangleToCellIdx.size() * 3 ); + + if ( resultValues.size() == 0 ) + { + textureCoords->setAll( cvf::Vec2f( 0.0, 1.0f ) ); + } + else + { + cvf::Vec2f* rawPtr = textureCoords->ptr(); + + for ( size_t triangleIdx = 0; triangleIdx < triangleToCellIdx.size(); triangleIdx++ ) + { + size_t resIdx = triangleToCellIdx[triangleIdx]; + float resValue = resultValues[resIdx]; + + size_t triangleVxIdx = triangleIdx * 3; + + if ( resValue == HUGE_VAL || resValue != resValue ) // a != a is true for NAN's + { + rawPtr[triangleVxIdx][1] = 1.0f; + rawPtr[triangleVxIdx + 1][1] = 1.0f; + rawPtr[triangleVxIdx + 2][1] = 1.0f; + } + else + { + rawPtr[triangleVxIdx] = mapper->mapToTextureCoord( resValue ); + rawPtr[triangleVxIdx + 1] = mapper->mapToTextureCoord( resValue ); + rawPtr[triangleVxIdx + 2] = mapper->mapToTextureCoord( resValue ); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivIntersectionResultsColoringTools::calculateGeoMechTensorXfTextureCoords( + cvf::Vec2fArray* textureCoords, + const cvf::Vec3fArray* triangelVertices, + const std::vector& vertexWeights, + RigGeoMechCaseData* caseData, + const RigFemResultAddress& resVarAddress, + int timeStepIdx, + const cvf::ScalarMapper* mapper ) +{ + RiuGeoMechXfTensorResultAccessor accessor( caseData->femPartResults(), resVarAddress, timeStepIdx ); + + textureCoords->resize( vertexWeights.size() ); + cvf::Vec2f* rawPtr = textureCoords->ptr(); + int vxCount = static_cast( vertexWeights.size() ); + int triCount = vxCount / 3; + +#pragma omp parallel for schedule( dynamic ) + for ( int triangleIdx = 0; triangleIdx < triCount; ++triangleIdx ) + { + int triangleVxStartIdx = triangleIdx * 3; + float values[3]; + + accessor.calculateInterpolatedValue( &( ( *triangelVertices )[triangleVxStartIdx] ), + &( vertexWeights[triangleVxStartIdx] ), + values ); + + rawPtr[triangleVxStartIdx + 0] = ( values[0] != std::numeric_limits::infinity() ) + ? mapper->mapToTextureCoord( values[0] ) + : cvf::Vec2f( 0.0f, 1.0f ); + rawPtr[triangleVxStartIdx + 1] = ( values[1] != std::numeric_limits::infinity() ) + ? mapper->mapToTextureCoord( values[1] ) + : cvf::Vec2f( 0.0f, 1.0f ); + rawPtr[triangleVxStartIdx + 2] = ( values[2] != std::numeric_limits::infinity() ) + ? mapper->mapToTextureCoord( values[2] ) + : cvf::Vec2f( 0.0f, 1.0f ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivIntersectionResultsColoringTools::calculatePlaneAngleTextureCoords( cvf::Vec2fArray* textureCoords, + const cvf::Vec3fArray* triangelVertices, + const RigFemResultAddress& resVarAddress, + const cvf::ScalarMapper* mapper ) +{ + textureCoords->resize( triangelVertices->size() ); + cvf::Vec2f* rawPtr = textureCoords->ptr(); + int vxCount = static_cast( triangelVertices->size() ); + int triCount = vxCount / 3; + + std::function operation; + if ( resVarAddress.componentName == "Pazi" ) + { + operation = []( const RiaOffshoreSphericalCoords& sphCoord ) { return (float)sphCoord.azi(); }; + } + else if ( resVarAddress.componentName == "Pinc" ) + { + operation = []( const RiaOffshoreSphericalCoords& sphCoord ) { return (float)sphCoord.inc(); }; + } + +#pragma omp parallel for schedule( dynamic ) + for ( int triangleIdx = 0; triangleIdx < triCount; ++triangleIdx ) + { + int triangleVxStartIdx = triangleIdx * 3; + + const cvf::Vec3f* triangle = &( ( *triangelVertices )[triangleVxStartIdx] ); + cvf::Mat3f rotMx = cvf::GeometryTools::computePlaneHorizontalRotationMx( triangle[1] - triangle[0], + triangle[2] - triangle[0] ); + + RiaOffshoreSphericalCoords sphCoord( + cvf::Vec3f( rotMx.rowCol( 0, 2 ), + rotMx.rowCol( 1, 2 ), + rotMx.rowCol( 2, 2 ) ) ); // Use Ez from the matrix as plane normal + + float angle = cvf::Math::toDegrees( operation( sphCoord ) ); + cvf::Vec2f texCoord = ( angle != std::numeric_limits::infinity() ) ? mapper->mapToTextureCoord( angle ) + : cvf::Vec2f( 0.0f, 1.0f ); + rawPtr[triangleVxStartIdx + 0] = texCoord; + rawPtr[triangleVxStartIdx + 1] = texCoord; + rawPtr[triangleVxStartIdx + 2] = texCoord; + } +} diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionResultsColoringTools.h b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionResultsColoringTools.h new file mode 100644 index 0000000000..3665579f66 --- /dev/null +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionResultsColoringTools.h @@ -0,0 +1,107 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2019- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfArray.h" + +#include "RivHexGridIntersectionTools.h" + +class RimEclipseResultDefinition; +class RimGeoMechResultDefinition; +class RimIntersectionHandle; + +class RivIntersectionGeometryGeneratorIF; +class RivTernaryScalarMapper; + +class RigResultAccessor; +class RigFemPart; +class RigGeoMechCaseData; +class RigFemResultAddress; + +namespace cvf +{ +class Part; +class ScalarMapper; +} // namespace cvf + +class RivIntersectionResultsColoringTools +{ +public: + static void updateCellResultColorStatic( size_t timeStepIndex, + RimIntersectionHandle* m_rimIntersectionBox, + const RivIntersectionGeometryGeneratorIF* m_intersectionBoxGenerator, + cvf::Part* m_intersectionBoxFaces, + cvf::Vec2fArray* m_intersectionBoxFacesTextureCoords ); + +private: + static void updateEclipseCellResultColors( const RimEclipseResultDefinition* eclipseResDef, + const cvf::ScalarMapper* scalarColorMapper, + size_t timeStepIndex, + bool isLightingDisabled, + const std::vector& triangleToCellIndexMapping, + cvf::Part* m_intersectionBoxFaces, + cvf::Vec2fArray* m_intersectionBoxFacesTextureCoords ); + + static void updateEclipseTernaryCellResultColors( const RimEclipseResultDefinition* eclipseResDef, + const RivTernaryScalarMapper* ternaryColorMapper, + size_t timeStepIndex, + bool isLightingDisabled, + const std::vector& triangleToCellIndexMapping, + cvf::Part* m_intersectionBoxFaces, + cvf::Vec2fArray* m_intersectionBoxFacesTextureCoords ); + + static void updateGeoMechCellResultColors( const RimGeoMechResultDefinition* geomResultDef, + size_t timeStepIndex, + const cvf::ScalarMapper* scalarColorMapper, + bool isLightingDisabled, + const RivIntersectionGeometryGeneratorIF* geomGenerator, + cvf::Part* m_intersectionBoxFaces, + cvf::Vec2fArray* m_intersectionBoxFacesTextureCoords ); + + static void calculateEclipseTextureCoordinates( cvf::Vec2fArray* textureCoords, + const std::vector& triangleToCellIdxMap, + const RigResultAccessor* resultAccessor, + const cvf::ScalarMapper* mapper ); + + static void calculateNodeOrElementNodeBasedGeoMechTextureCoords( + cvf::Vec2fArray* textureCoords, + const std::vector& vertexWeights, + const std::vector& resultValues, + bool isElementNodalResult, + const RigFemPart* femPart, + const cvf::ScalarMapper* mapper ); + + static void calculateElementBasedGeoMechTextureCoords( cvf::Vec2fArray* textureCoords, + const std::vector& resultValues, + const std::vector& triangleToCellIdx, + const cvf::ScalarMapper* mapper ); + + static void calculateGeoMechTensorXfTextureCoords( cvf::Vec2fArray* textureCoords, + const cvf::Vec3fArray* triangelVertices, + const std::vector& vertexWeights, + RigGeoMechCaseData* caseData, + const RigFemResultAddress& resVarAddress, + int timeStepIdx, + const cvf::ScalarMapper* mapper ); + + static void calculatePlaneAngleTextureCoords( cvf::Vec2fArray* textureCoords, + const cvf::Vec3fArray* triangelVertices, + const RigFemResultAddress& resVarAddress, + const cvf::ScalarMapper* mapper ); +};