diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp index 5ed6310504..52cc6d65dd 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp @@ -112,6 +112,7 @@ void RivFemElmVisibilityCalculator::computePropertyVisibility(cvf::UByteArray* c for (size_t i = 0; i < propFilterColl->propertyFilters().size(); i++) { RimGeoMechPropertyFilter* propertyFilter = propFilterColl->propertyFilters()[i]; + if (!propertyFilter->isActiveAndHasResult()) continue; const RimCellFilter::FilterModeType filterType = propertyFilter->filterMode(); @@ -173,7 +174,7 @@ void RivFemElmVisibilityCalculator::computePropertyVisibility(cvf::UByteArray* c if (!(*cellVisibility)[cellIndex]) continue; double scalarValue = resVals[cellIndex]; - evaluateAndSetCellVisibiliy(scalarValue, lowerBound, upperBound, filterType, cellVisibility, cellIndex); + evaluateAndSetCellVisibiliy(cellIndex, scalarValue, lowerBound, upperBound, filterType, cellVisibility); } } else if (resVarAddress.resultPosType == RIG_ELEMENT_NODAL_FACE) @@ -186,7 +187,7 @@ void RivFemElmVisibilityCalculator::computePropertyVisibility(cvf::UByteArray* c for (int fpIdx = 0; fpIdx < 24; ++fpIdx) { double scalarValue = resVals[cellIndex * 24 + fpIdx]; - evaluateAndSetCellVisibiliy(scalarValue, lowerBound, upperBound, filterType, cellVisibility, cellIndex); + evaluateAndSetCellVisibiliy(cellIndex, scalarValue, lowerBound, upperBound, filterType, cellVisibility); } } } @@ -214,7 +215,7 @@ void RivFemElmVisibilityCalculator::computePropertyVisibility(cvf::UByteArray* c } double scalarValue = resVals[resultValueIndex]; - evaluateAndSetCellVisibiliy(scalarValue, lowerBound, upperBound, filterType, cellVisibility, cellIndex); + evaluateAndSetCellVisibiliy(cellIndex, scalarValue, lowerBound, upperBound, filterType, cellVisibility); } } } @@ -224,7 +225,12 @@ void RivFemElmVisibilityCalculator::computePropertyVisibility(cvf::UByteArray* c //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivFemElmVisibilityCalculator::evaluateAndSetCellVisibiliy(double scalarValue, double lowerBound, double upperBound, const RimCellFilter::FilterModeType filterType, cvf::UByteArray* cellVisibility, int cellIndex) +void RivFemElmVisibilityCalculator::evaluateAndSetCellVisibiliy(int cellIndex, + double scalarValue, + double lowerBound, + double upperBound, + const RimCellFilter::FilterModeType filterType, + cvf::UByteArray* cellVisibility) { if (lowerBound <= scalarValue && scalarValue <= upperBound) { diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.h b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.h index bd1cb66506..659661ac41 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.h +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.h @@ -46,15 +46,16 @@ public: const cvf::UByteArray* rangeFilterVisibility, RimGeoMechPropertyFilterCollection* propFilterColl); - static void evaluateAndSetCellVisibiliy(double scalarValue, double lowerBound, double upperBound, + static void evaluateAndSetCellVisibiliy(int cellIndex, + double scalarValue, + double lowerBound, + double upperBound, const RimCellFilter::FilterModeType filterType, - cvf::UByteArray* cellVisibility, int cellIndex); - + cvf::UByteArray* cellVisibility); static void computeOverriddenCellVisibility(cvf::UByteArray* elmVisibilities, const RigFemPart* femPart , RimViewController* masterViewLink); - }; diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp index bff87fafa9..e2001740fa 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp @@ -160,31 +160,24 @@ void RivIntersectionBoxPartMgr::updateCellResultColor(size_t timeStepIndex) RigFemResultAddress resVarAddress = cellResultColors->resultAddress(); - const std::vector &vertexWeights = m_intersectionBoxGenerator->triangleVxToCellCornerInterpolationWeights(); - const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); + const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); - if (!(resVarAddress.resultPosType == RIG_ELEMENT_NODAL_FACE) ) + if (resVarAddress.resultPosType == RIG_ELEMENT) { - // 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); + const std::vector& triangleToCellIdx = m_intersectionBoxGenerator->triangleToCellIndex(); - const std::vector& resultValues = caseData->femPartResults()->resultValues(resVarAddress, 0, (int)timeStepIndex); - RigFemPart* femPart = caseData->femParts()->part(0); - bool isElementNodalResult = !(resVarAddress.resultPosType == RIG_NODAL); - - RivIntersectionPartMgr::calculateGeoMechTextureCoords(m_intersectionBoxFacesTextureCoords.p(), - vertexWeights, - resultValues, - isElementNodalResult, - femPart, - mapper); + RivIntersectionPartMgr::calculateElementBasedGeoMechTextureCoords(m_intersectionBoxFacesTextureCoords.p(), + resultValues, + triangleToCellIdx, + mapper); } - else + else if (resVarAddress.resultPosType == RIG_ELEMENT_NODAL_FACE) { // Special direction sensitive result calculation const cvf::Vec3fArray* triangelVxes = m_intersectionBoxGenerator->triangleVxes(); - if ( resVarAddress.componentName == "Pazi" || resVarAddress.componentName == "Pinc" ) + if (resVarAddress.componentName == "Pazi" || resVarAddress.componentName == "Pinc") { RivIntersectionPartMgr::calculatePlaneAngleTextureCoords(m_intersectionBoxFacesTextureCoords.p(), triangelVxes, @@ -193,15 +186,34 @@ void RivIntersectionBoxPartMgr::updateCellResultColor(size_t timeStepIndex) } else { + const std::vector &vertexWeights = m_intersectionBoxGenerator->triangleVxToCellCornerInterpolationWeights(); + RivIntersectionPartMgr::calculateGeoMechTensorXfTextureCoords(m_intersectionBoxFacesTextureCoords.p(), - triangelVxes, - vertexWeights, - caseData, - resVarAddress, - (int)timeStepIndex, - mapper); + triangelVxes, + vertexWeights, + caseData, + resVarAddress, + (int)timeStepIndex, + mapper); } } + 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); + const std::vector &vertexWeights = m_intersectionBoxGenerator->triangleVxToCellCornerInterpolationWeights(); + + RivIntersectionPartMgr::calculateNodeOrElementNodeBasedGeoMechTextureCoords(m_intersectionBoxFacesTextureCoords.p(), + vertexWeights, + resultValues, + isElementNodalResult, + femPart, + mapper); + } RivScalarMapperUtils::applyTextureResultsToPart(m_intersectionBoxFaces.p(), m_intersectionBoxFacesTextureCoords.p(), diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp index f873631b24..c2c5276573 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp @@ -168,39 +168,35 @@ void RivIntersectionPartMgr::updateCellResultColor(size_t timeStepIndex) RigFemResultAddress resVarAddress = cellResultColors->resultAddress(); - const std::vector &vertexWeights = m_crossSectionGenerator->triangleVxToCellCornerInterpolationWeights(); - const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); + const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); - if(!(resVarAddress.resultPosType == RIG_ELEMENT_NODAL_FACE) ) + if (resVarAddress.resultPosType == RIG_ELEMENT) { - // 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); + const std::vector& triangleToCellIdx = m_crossSectionGenerator->triangleToCellIndex(); - const std::vector& resultValues = caseData->femPartResults()->resultValues(resVarAddress, 0, (int)timeStepIndex); - RigFemPart* femPart = caseData->femParts()->part(0); - bool isElementNodalResult = !(resVarAddress.resultPosType == RIG_NODAL); + RivIntersectionPartMgr::calculateElementBasedGeoMechTextureCoords(m_crossSectionFacesTextureCoords.p(), + resultValues, + triangleToCellIdx, + mapper); - RivIntersectionPartMgr::calculateGeoMechTextureCoords(m_crossSectionFacesTextureCoords.p(), - vertexWeights, - resultValues, - isElementNodalResult, - femPart, - mapper); } - else + else if(resVarAddress.resultPosType == RIG_ELEMENT_NODAL_FACE) { // Special direction sensitive result calculation const cvf::Vec3fArray* triangelVxes = m_crossSectionGenerator->triangleVxes(); - if ( resVarAddress.componentName == "Pazi" || resVarAddress.componentName == "Pinc" ) + if (resVarAddress.componentName == "Pazi" || resVarAddress.componentName == "Pinc") { RivIntersectionPartMgr::calculatePlaneAngleTextureCoords(m_crossSectionFacesTextureCoords.p(), - triangelVxes, + triangelVxes, resVarAddress, mapper); } else { + const std::vector &vertexWeights = m_crossSectionGenerator->triangleVxToCellCornerInterpolationWeights(); + RivIntersectionPartMgr::calculateGeoMechTensorXfTextureCoords(m_crossSectionFacesTextureCoords.p(), triangelVxes, vertexWeights, @@ -210,6 +206,23 @@ void RivIntersectionPartMgr::updateCellResultColor(size_t timeStepIndex) mapper); } } + 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); + const std::vector &vertexWeights = m_crossSectionGenerator->triangleVxToCellCornerInterpolationWeights(); + + RivIntersectionPartMgr::calculateNodeOrElementNodeBasedGeoMechTextureCoords(m_crossSectionFacesTextureCoords.p(), + vertexWeights, + resultValues, + isElementNodalResult, + femPart, + mapper); + } RivScalarMapperUtils::applyTextureResultsToPart(m_crossSectionFaces.p(), m_crossSectionFacesTextureCoords.p(), @@ -224,12 +237,12 @@ void RivIntersectionPartMgr::updateCellResultColor(size_t timeStepIndex) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivIntersectionPartMgr::calculateGeoMechTextureCoords(cvf::Vec2fArray* textureCoords, - const std::vector &vertexWeights, - const std::vector &resultValues, - bool isElementNodalResult, - const RigFemPart* femPart, - const cvf::ScalarMapper* mapper) +void RivIntersectionPartMgr::calculateNodeOrElementNodeBasedGeoMechTextureCoords(cvf::Vec2fArray* textureCoords, + const std::vector &vertexWeights, + const std::vector &resultValues, + bool isElementNodalResult, + const RigFemPart* femPart, + const cvf::ScalarMapper* mapper) { textureCoords->resize(vertexWeights.size()); @@ -250,8 +263,16 @@ void RivIntersectionPartMgr::calculateGeoMechTextureCoords(cvf::Vec2fArray* text int weightCount = vertexWeights[triangleVxIdx].size(); for (int wIdx = 0; wIdx < weightCount; ++wIdx) { - size_t resIdx = isElementNodalResult ? vertexWeights[triangleVxIdx].vxId(wIdx) : - femPart->nodeIdxFromElementNodeResultIdx(vertexWeights[triangleVxIdx].vxId(wIdx)); + size_t resIdx; + if (isElementNodalResult) + { + resIdx = vertexWeights[triangleVxIdx].vxId(wIdx); + } + else + { + resIdx = femPart->nodeIdxFromElementNodeResultIdx(vertexWeights[triangleVxIdx].vxId(wIdx)); + } + resValue += resultValues[resIdx] * vertexWeights[triangleVxIdx].weight(wIdx); } @@ -267,6 +288,47 @@ void RivIntersectionPartMgr::calculateGeoMechTextureCoords(cvf::Vec2fArray* text } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivIntersectionPartMgr::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 (int triangleIdx = 0; triangleIdx < triangleToCellIdx.size(); triangleIdx++) + { + size_t resIdx = triangleToCellIdx[triangleIdx]; + float resValue = resultValues[resIdx]; + + int 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); + } + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.h b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.h index b585178447..14cb3be11b 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.h +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.h @@ -80,12 +80,17 @@ public: const RigResultAccessor* resultAccessor, const cvf::ScalarMapper* mapper); - static void calculateGeoMechTextureCoords(cvf::Vec2fArray* textureCoords, - const std::vector &vertexWeights, - const std::vector &resultValues, - bool isElementNodalResult, - const RigFemPart* femPart, - 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,