diff --git a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h index f05d7e1a49..0c37fb84bc 100644 --- a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h +++ b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h @@ -43,7 +43,64 @@ public: float opacityLevel); }; +/* + Thoughts on organizing the texture coords generation a bit. + Conceptually several mappings takes place: + + 1. ResultValues to ResultPointValues <-- Eg. Cell Center values to CellFace Values + 2. ResultPointValues to GeometryPointValues <-- Eg. CellCenter Values to Triangle Vertex + 3. GeometryPointValues to TextureCoordinates/Colors <-- Handled by ScalarMapper + + When evaluating, we normally use the geometry as starting point, as that often is + a subset of the total results/geometry domain. + + To make this efficient, a minimum of internal storage should be used, so we want + to make the mappings as a set of functions called for each (or a few) texture + coordinate positions + + The mapping is then actually accessed in the opposite way of the above, while calculated in the 1-3 order + + Accessing correct values: + GeometryPointIdx->ResultPointIdx->ResultValueIdx + Calculating color: + ResultValue->ResultPointValue->GeometryPointValue->Texture/ColorValue + + In ResInsight (for now) + the ResultPointValue will be the same for all the corresponding GeometryPoints, + which means each quadvertex has the same texcoord for all corners. + + Proposal: + ---------- + Let the FaceValue to Face vertex texture coordinate mapping be the same for all. + Extract that from the code floating around. + + Create a PrimitiveFaceIdx to CellIdx with Face mapper class that handles the lookup, + created by the geometry generation + + Create separate calculators/mappers/Strategies to create FaceValues from results. + + Test Code + ----------- + // Example code + // 1. CellCenterToCellFace + // 2. CellFace to Quad Corners + // 3. Quad Corner Values to tex coords + + texCoords.resize(m_quadsToGridCells.size()*4); + for (i = 0; i < m_quadsToGridCells.size(); ++i) + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(dataAccessObject->cellScalar(m_quadsToGridCells[i])); + ResValue ResPoint To ResValue + texCoords[i*4 + 0] = texCoord; + texCoords[i*4 + 1] = texCoord; + texCoords[i*4 + 2] = texCoord; + texCoords[i*4 + 3] = texCoord; + } + + + +*/ //================================================================================================== // diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index 193571e2b8..df5220b023 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -294,7 +294,13 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* // 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 // we turn that off for particular cells, if the well pipe is not shown for that cell - + + setResultsTransparentForWellCells( + cellResultSlot->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex), + eclipseCase->gridCellToWellIndex(m_grid->gridIndex()), + m_surfaceGenerator.quadToCellFaceMapper(), + m_surfaceFacesTextureCoords.p()); + /* if (m_opacityLevel < 1.0f ) { const std::vector& isWellPipeVisible = cellResultSlot->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex); @@ -317,10 +323,11 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* } } } - - cvf::DrawableGeo* dg = dynamic_cast(m_surfaceFaces->drawable()); + + */ if (surfaceFacesColorArray.notNull()) { + cvf::DrawableGeo* dg = dynamic_cast(m_surfaceFaces->drawable()); if (dg) { dg->setColorArray(surfaceFacesColorArray.p()); @@ -333,19 +340,7 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* } else { - if (dg) - { - dg->setTextureCoordArray(m_surfaceFacesTextureCoords.p()); - } - - caf::PolygonOffset polygonOffset = caf::PO_1; - caf::ScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); - - scalarEffgen.setOpacityLevel(m_opacityLevel); - - cvf::ref scalarEffect = scalarEffgen.generateEffect(); - - m_surfaceFaces->setEffect(scalarEffect.p()); + applyResultsToPart(m_surfaceFaces.p(), m_surfaceFacesTextureCoords.p(), mapper ); } } @@ -363,7 +358,14 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* if (dataAccessObject.isNull()) return; m_faultGenerator.textureCoordinates(m_faultFacesTextureCoords.p(), dataAccessObject.p(), mapper); - + + setResultsTransparentForWellCells( + cellResultSlot->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex), + eclipseCase->gridCellToWellIndex(m_grid->gridIndex()), + m_surfaceGenerator.quadToCellFaceMapper(), + m_faultFacesTextureCoords.p()); + + /* if (m_opacityLevel < 1.0f ) { const std::vector& isWellPipeVisible = cellResultSlot->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex); @@ -387,18 +389,54 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* } } } + */ + applyResultsToPart(m_faultFaces.p(), m_faultFacesTextureCoords.p(), mapper); + } +} - cvf::DrawableGeo* dg = dynamic_cast(m_faultFaces->drawable()); - if (dg) dg->setTextureCoordArray(m_faultFacesTextureCoords.p()); +cvf::ref RivGridPartMgr::createScalarMapperEffect(const cvf::ScalarMapper* mapper) +{ + caf::PolygonOffset polygonOffset = caf::PO_1; + caf::ScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); + scalarEffgen.setOpacityLevel(m_opacityLevel); + cvf::ref scalarEffect = scalarEffgen.generateEffect(); + return scalarEffect; +} - caf::PolygonOffset polygonOffset = caf::PO_1; - caf::ScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); +void RivGridPartMgr::applyResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper) +{ + cvf::DrawableGeo* dg = dynamic_cast(part->drawable()); + if (dg) dg->setTextureCoordArray(m_faultFacesTextureCoords.p()); - scalarEffgen.setOpacityLevel(m_opacityLevel); + cvf::ref scalarEffect = createScalarMapperEffect(mapper); + part->setEffect(scalarEffect.p()); +} - cvf::ref scalarEffect = scalarEffgen.generateEffect(); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivGridPartMgr::setResultsTransparentForWellCells(const std::vector& isWellPipeVisibleForWellIndex, + const cvf::UIntArray* gridCellToWellIndexMap, + const cvf::StructGridQuadToCellFaceMapper* quadsToCellFaceMapper, + cvf::Vec2fArray* resultTextureCoords) +{ + if (m_opacityLevel < 1.0f ) + { + for(size_t i = 0; i < resultTextureCoords->size(); ++i) + { + if ((*resultTextureCoords)[i].y() == 1.0f) continue; // Do not touch undefined values - m_faultFaces->setEffect(scalarEffect.p()); + size_t quadIdx = i/4; + size_t cellIndex = quadsToCellFaceMapper->cellIndex(quadIdx); + cvf::uint wellIndex = gridCellToWellIndexMap->get(cellIndex); + if (wellIndex != cvf::UNDEFINED_UINT) + { + if ( !isWellPipeVisibleForWellIndex[wellIndex]) + { + (*resultTextureCoords)[i].y() = 0; // Set the Y texture coordinate to the opaque line in the texture + } + } + } } } diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.h b/ApplicationCode/ModelVisualization/RivGridPartMgr.h index d866bd5f34..c395392902 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.h @@ -90,7 +90,12 @@ public: private: void generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder, bool faultGeometry); - + void applyResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper); + cvf::ref createScalarMapperEffect(const cvf::ScalarMapper* mapper); + void setResultsTransparentForWellCells(const std::vector& isWellPipeVisibleForWellIndex, + const cvf::UIntArray* gridCellToWellIndexMap, + const cvf::StructGridQuadToCellFaceMapper* quadsToCellFaceMapper, + cvf::Vec2fArray* resultTextureCoords); private: size_t m_gridIdx; cvf::cref m_grid;