diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index c44afca889..13ccdd27cd 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -246,25 +246,32 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* { CVF_ASSERT(cellResultSlot); - size_t scalarSetIndex = cellResultSlot->gridScalarIndex(); + const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper(); - - // If the result is static, only read that. - size_t resTimeStepIdx = timeStepIndex; - if (cellResultSlot->hasStaticResult()) resTimeStepIdx = 0; - - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); - RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); - cvf::ref dataAccessObject = eclipseCase->dataAccessObject(m_grid.p(), porosityModel, resTimeStepIdx, scalarSetIndex); - - if (dataAccessObject.isNull()) return; // Outer surface if (m_surfaceFaces.notNull()) { - m_surfaceGenerator.textureCoordinates(m_surfaceFacesTextureCoords.p(), dataAccessObject.p(), mapper); + if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) + { + updateTransmissibilityCellResultColor(timeStepIndex, cellResultSlot); + } + else + { + size_t scalarSetIndex = cellResultSlot->gridScalarIndex(); + + // If the result is static, only read that. + size_t resTimeStepIdx = timeStepIndex; + if (cellResultSlot->hasStaticResult()) resTimeStepIdx = 0; + + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); + cvf::ref dataAccessObject = eclipseCase->dataAccessObject(m_grid.p(), porosityModel, resTimeStepIdx, scalarSetIndex); + if (dataAccessObject.isNull()) return; + + m_surfaceGenerator.textureCoordinates(m_surfaceFacesTextureCoords.p(), dataAccessObject.p(), mapper); + } // if this gridpart manager is set to have some transparency, we // interpret it as we are displaying beeing wellcells. The cells are then transparent by default, but @@ -309,6 +316,16 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* // Faults if (m_faultFaces.notNull()) { + size_t scalarSetIndex = cellResultSlot->gridScalarIndex(); + + // If the result is static, only read that. + size_t resTimeStepIdx = timeStepIndex; + if (cellResultSlot->hasStaticResult()) resTimeStepIdx = 0; + + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); + cvf::ref dataAccessObject = eclipseCase->dataAccessObject(m_grid.p(), porosityModel, resTimeStepIdx, scalarSetIndex); + if (dataAccessObject.isNull()) return; + m_faultGenerator.textureCoordinates(m_faultFacesTextureCoords.p(), dataAccessObject.p(), mapper); if (m_opacityLevel < 1.0f ) @@ -407,3 +424,117 @@ RivGridPartMgr::~RivGridPartMgr() if (m_surfaceFaces.notNull()) m_surfaceFaces->deleteOrReleaseOpenGLResources(); #endif } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivGridPartMgr::updateTransmissibilityCellResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot) +{ + const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper(); + if (!mapper) return; + + const RimReservoirCellResultsStorage* gridCellResults = cellResultSlot->currentGridCellResults(); + if (!gridCellResults) return; + + size_t tranPosXScalarSetIndex = gridCellResults->cellResults()->findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANX"); + size_t tranPosYScalarSetIndex = gridCellResults->cellResults()->findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANY"); + size_t tranPosZScalarSetIndex = gridCellResults->cellResults()->findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANZ"); + if (tranPosXScalarSetIndex == cvf::UNDEFINED_SIZE_T || + tranPosYScalarSetIndex == cvf::UNDEFINED_SIZE_T || + tranPosZScalarSetIndex == cvf::UNDEFINED_SIZE_T) + { + return; + } + + // If the result is static, only read that. + size_t resTimeStepIdx = 0; + + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); + + RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); + if (!eclipseCase) return; + + cvf::ref dataAccessObjectTranX = eclipseCase->dataAccessObject(m_grid.p(), porosityModel, resTimeStepIdx, tranPosXScalarSetIndex); + cvf::ref dataAccessObjectTranY = eclipseCase->dataAccessObject(m_grid.p(), porosityModel, resTimeStepIdx, tranPosYScalarSetIndex); + cvf::ref dataAccessObjectTranZ = eclipseCase->dataAccessObject(m_grid.p(), porosityModel, resTimeStepIdx, tranPosZScalarSetIndex); + + // Outer surface + if (m_surfaceFaces.notNull()) + { + const std::vector& quadsToFaceTypes = m_surfaceGenerator.quadToFace(); + const std::vector& quadsToGridCells = m_surfaceGenerator.quadToGridCellIndices(); + cvf::Vec2fArray* textureCoords = m_surfaceFacesTextureCoords.p(); + + size_t numVertices = quadsToGridCells.size()*4; + + textureCoords->resize(numVertices); + cvf::Vec2f* rawPtr = textureCoords->ptr(); + + double cellScalarValue; + cvf::Vec2f texCoord; + +#pragma omp parallel for private(texCoord, cellScalarValue) + for (int idx = 0; idx < static_cast(quadsToGridCells.size()); idx++) + { + if (quadsToFaceTypes[idx] == cvf::StructGridInterface::POS_I) + { + cellScalarValue = dataAccessObjectTranX->cellScalar(quadsToGridCells[idx]); + } + else if (quadsToFaceTypes[idx] == cvf::StructGridInterface::NEG_I) + { + size_t i, j, k, neighborGridCellIdx; + m_grid->ijkFromCellIndex(quadsToGridCells[idx], &i, &j, &k); + + if(m_grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::POS_I, &neighborGridCellIdx)) + { + cellScalarValue = dataAccessObjectTranX->cellScalar(neighborGridCellIdx); + } + } + else if (quadsToFaceTypes[idx] == cvf::StructGridInterface::POS_J) + { + cellScalarValue = dataAccessObjectTranY->cellScalar(quadsToGridCells[idx]); + } + else if (quadsToFaceTypes[idx] == cvf::StructGridInterface::NEG_J) + { + size_t i, j, k, neighborGridCellIdx; + m_grid->ijkFromCellIndex(quadsToGridCells[idx], &i, &j, &k); + + if(m_grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::POS_J, &neighborGridCellIdx)) + { + cellScalarValue = dataAccessObjectTranY->cellScalar(neighborGridCellIdx); + } + } + else if (quadsToFaceTypes[idx] == cvf::StructGridInterface::POS_K) + { + cellScalarValue = dataAccessObjectTranZ->cellScalar(quadsToGridCells[idx]); + } + else if (quadsToFaceTypes[idx] == cvf::StructGridInterface::NEG_K) + { + size_t i, j, k, neighborGridCellIdx; + m_grid->ijkFromCellIndex(quadsToGridCells[idx], &i, &j, &k); + + if(m_grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::POS_K, &neighborGridCellIdx)) + { + cellScalarValue = dataAccessObjectTranZ->cellScalar(neighborGridCellIdx); + } + } + else + { + cellScalarValue = HUGE_VAL; + } + + 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 < 4; j++) + { + rawPtr[idx*4 + j] = texCoord; + } + } + } +} + diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.h b/ApplicationCode/ModelVisualization/RivGridPartMgr.h index 40e28616ee..302b882b04 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.h @@ -43,6 +43,20 @@ class RimFaultCollection; /// //================================================================================================== +class RivTransmissibilityColorMapper +{ +public: + static void transmissibilitiesTextureCoordinates(cvf::Vec2fArray* textureCoords, + const cvf::StructGridScalarDataAccess* dataAccessObjectTranX, + const cvf::StructGridScalarDataAccess* dataAccessObjectTranY, + const cvf::StructGridScalarDataAccess* dataAccessObjectTranZ, + const cvf::ScalarMapper* mapper, + const std::vector& m_quadsToFaceTypes, + const std::vector& m_quadsToGridCells + ); +}; + + class RivGridPartMgr: public cvf::Object { public: @@ -59,9 +73,12 @@ public: void appendPartsToModel(cvf::ModelBasicList* model); + void updateTransmissibilityCellResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot); private: void generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder, bool faultGeometry); + + private: size_t m_gridIdx; diff --git a/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.cpp b/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.cpp index 0cd2bfe5ee..6ad2889f05 100644 --- a/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.cpp +++ b/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.cpp @@ -341,8 +341,6 @@ void StructGridGeometryGenerator::computeArrays() if (visibleFaces.size() > 0) { - size_t cellIndex = m_grid->cellIndexFromIJK(i, j, k); - cvf::Vec3d cornerVerts[8]; m_grid->cellCornerVertices(cellIndex, cornerVerts);