From 87ef7a01b9629a152b7fb473aff7663af680a6a2 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 12 Mar 2026 14:40:26 +0100 Subject: [PATCH] ContourMap: Add texture-based rendering as default rendering mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract and clean up prototype from contour-map-01 branch: - RivContourMapProjectionPartMgr: add appendProjectionAsTexturedQuad(), createSingleTexturedQuadPart(), createXYPlaneQuadGeoWithTexCoords(), and createTexture() — renders the map as a single GPU-textured quad with transparency (alpha=0) for undefined/infinity cells - RimContourMapProjection: add m_showTextureImage (default true) and m_showTrianglesWithColor (default false) PDM fields; guard triangle mesh generation when showTrianglesWithColor() is false - RimEclipseContourMapView, RimGeoMechContourMapView: branch appendContourMapProjectionToModel() to use texture or triangle path based on the new flags; Statistics view inherits Eclipse path Prototype dead code (debug file save, SurfaceEffectGenerator fallback, redundant createImage()) not carried forward. --- .../RivContourMapProjectionPartMgr.cpp | 166 ++++++++++++++++++ .../RivContourMapProjectionPartMgr.h | 14 ++ .../ContourMap/RimContourMapProjection.cpp | 37 +++- .../ContourMap/RimContourMapProjection.h | 4 + .../ContourMap/RimEclipseContourMapView.cpp | 24 ++- .../GeoMech/RimGeoMechContourMapView.cpp | 24 ++- 6 files changed, 250 insertions(+), 19 deletions(-) diff --git a/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp b/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp index 9a6661c5d9..40e53322d0 100644 --- a/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp +++ b/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp @@ -22,6 +22,7 @@ #include "RiaFontCache.h" #include "ContourMap/RigContourMapGrid.h" +#include "ContourMap/RigContourMapProjection.h" #include "ContourMap/RigContourPolygonsTools.h" #include "RivMeshLinesSourceInfo.h" @@ -39,7 +40,15 @@ #include "cvfPart.h" #include "cvfPrimitiveSetIndexedUInt.h" #include "cvfRay.h" +#include "cvfRenderStateBlending.h" +#include "cvfRenderStateTextureBindings.h" +#include "cvfSampler.h" #include "cvfScalarMapper.h" +#include "cvfShaderProgram.h" +#include "cvfShaderProgramGenerator.h" +#include "cvfShaderSourceProvider.h" +#include "cvfTexture.h" +#include "cvfTextureImage.h" #include "cvfViewport.h" #include "cvfqtUtils.h" @@ -56,6 +65,12 @@ RivContourMapProjectionPartMgr::RivContourMapProjectionPartMgr( caf::PdmObject* m_pdmObject = pdmObject; m_labelEffect = new cvf::Effect; + + cvf::ShaderProgramGenerator gen( "Texturing", cvf::ShaderSourceProvider::instance() ); + gen.addVertexCode( cvf::ShaderSourceRepository::vs_Standard ); + gen.addFragmentCode( cvf::ShaderSourceRepository::src_Texture ); + gen.addFragmentCode( cvf::ShaderSourceRepository::fs_Unlit ); + m_textureShaderProg = gen.generate(); } //-------------------------------------------------------------------------------------------------- @@ -585,3 +600,154 @@ bool RivContourMapProjectionPartMgr::lineOverlapsWithPreviousContourLevel( const { return RigContourPolygonsTools::lineOverlapsWithContourPolygons( lineCenter, previousLevel, tolerance ); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivContourMapProjectionPartMgr::appendProjectionAsTexturedQuad( cvf::ModelBasicList* model, + const caf::DisplayCoordTransform* displayCoordTransform, + cvf::ScalarMapper* scalarMapper, + const RigContourMapProjection& contourMapProjection, + const RigContourMapGrid& contourMapGrid ) +{ + auto expandedBB = contourMapGrid.expandedBoundingBox(); + + cvf::Vec3dArray domainCoords; + domainCoords.reserve( 4 ); + domainCoords.add( expandedBB.min() ); + domainCoords.add( cvf::Vec3d( expandedBB.max().x(), expandedBB.min().y(), expandedBB.min().z() ) ); + domainCoords.add( expandedBB.max() ); + domainCoords.add( cvf::Vec3d( expandedBB.min().x(), expandedBB.max().y(), expandedBB.min().z() ) ); + + double zValueForContourMap = contourMapGrid.origin3d().z(); + zValueForContourMap += 0.3 * zValueForContourMap; + + cvf::Vec3dArray displayCoords; + displayCoords.reserve( 4 ); + for ( int i = 0; i < 4; i++ ) + { + auto displayCoord = displayCoordTransform->transformToDisplayCoord( domainCoords[i] ); + displayCoord.z() = zValueForContourMap; + displayCoords.add( displayCoord ); + } + + auto textureImage = RivContourMapProjectionPartMgr::createTexture( &contourMapProjection, scalarMapper ); + + bool transparent = true; + auto part = createSingleTexturedQuadPart( displayCoords, textureImage, transparent ); + part->setSourceInfo( new RivObjectSourceInfo( m_pdmObject.p() ) ); + part->setPriority( RivPartPriority::BaseLevel ); + + model->addPart( part.p() ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RivContourMapProjectionPartMgr::createXYPlaneQuadGeoWithTexCoords( const cvf::Vec3dArray& cornerPoints ) +{ + cvf::ref vertices = new cvf::Vec3fArray; + vertices->reserve( 4 ); + for ( const auto& v : cornerPoints ) + { + vertices->add( cvf::Vec3f( v ) ); + } + + cvf::ref texCoords = new cvf::Vec2fArray; + texCoords->reserve( 4 ); + texCoords->add( cvf::Vec2f( 0, 0 ) ); + texCoords->add( cvf::Vec2f( 1, 0 ) ); + texCoords->add( cvf::Vec2f( 1, 1 ) ); + texCoords->add( cvf::Vec2f( 0, 1 ) ); + + cvf::ref geo = new cvf::DrawableGeo; + geo->setVertexArray( vertices.p() ); + geo->setTextureCoordArray( texCoords.p() ); + + cvf::ref indices = new cvf::UIntArray; + indices->reserve( 6 ); + for ( uint i : { 0u, 1u, 2u, 0u, 2u, 3u } ) + { + indices->add( i ); + } + + cvf::ref primSet = new cvf::PrimitiveSetIndexedUInt( cvf::PT_TRIANGLES ); + primSet->setIndices( indices.p() ); + geo->addPrimitiveSet( primSet.p() ); + geo->computeNormals(); + + return geo; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RivContourMapProjectionPartMgr::createSingleTexturedQuadPart( const cvf::Vec3dArray& cornerPoints, + cvf::ref image, + bool transparent ) +{ + cvf::ref part = new cvf::Part; + + cvf::ref geo = createXYPlaneQuadGeoWithTexCoords( cornerPoints ); + + cvf::ref texture = new cvf::Texture( image.p() ); + cvf::ref sampler = new cvf::Sampler; + sampler->setMinFilter( cvf::Sampler::LINEAR ); + sampler->setMagFilter( cvf::Sampler::NEAREST ); + sampler->setWrapModeS( cvf::Sampler::CLAMP_TO_EDGE ); + sampler->setWrapModeT( cvf::Sampler::CLAMP_TO_EDGE ); + + cvf::ref textureBindings = new cvf::RenderStateTextureBindings; + textureBindings->addBinding( texture.p(), sampler.p(), "u_texture2D" ); + + cvf::ref eff = new cvf::Effect; + eff->setRenderState( textureBindings.p() ); + eff->setShaderProgram( m_textureShaderProg.p() ); + + if ( transparent ) + { + part->setPriority( RivPartPriority::PartType::TransparentSeismic ); + cvf::ref blending = new cvf::RenderStateBlending; + blending->configureTransparencyBlending(); + eff->setRenderState( blending.p() ); + } + + part->setDrawable( geo.p() ); + part->updateBoundingBox(); + part->setEffect( eff.p() ); + + return part; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::TextureImage* RivContourMapProjectionPartMgr::createTexture( const RigContourMapProjection* contourMapProjection, + cvf::ScalarMapper* scalarMapper ) +{ + if ( !contourMapProjection || !scalarMapper ) return nullptr; + + auto vertexSizeIJ = contourMapProjection->numberOfVerticesIJ(); + int width = static_cast( vertexSizeIJ.x() ); + int height = static_cast( vertexSizeIJ.y() ); + + cvf::TextureImage* textureImage = new cvf::TextureImage(); + textureImage->allocate( width, height ); + + auto dataValues = contourMapProjection->aggregatedVertexResultsFiltered(); + + for ( int y = 0; y < height; ++y ) + { + for ( int x = 0; x < width; ++x ) + { + size_t index = contourMapProjection->vertexIndex( x, y ); + double valueAtVertex = dataValues[index]; + auto color = scalarMapper->mapToColor( valueAtVertex ); + + int transparency = ( valueAtVertex != std::numeric_limits::infinity() ) ? 255 : 0; + textureImage->setPixel( x, y, cvf::Color4ub( color, transparency ) ); + } + } + + return textureImage; +} diff --git a/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.h b/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.h index e2b2dc0e07..5566810f57 100644 --- a/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.h +++ b/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.h @@ -32,6 +32,7 @@ #include "cvfVector4.h" class RigContourMapGrid; +class RigContourMapProjection; namespace cvf { @@ -40,6 +41,7 @@ class ScalarMapper; class Color3f; class ModelBasicList; class Part; +class TextureImage; } // namespace cvf class RivContourMapProjectionPartMgr : public cvf::Object @@ -70,6 +72,12 @@ public: const cvf::Vec2d& pickPoint, const RigContourMapGrid& contourMapGrid ) const; + void appendProjectionAsTexturedQuad( cvf::ModelBasicList* model, + const caf::DisplayCoordTransform* displayCoordTransform, + cvf::ScalarMapper* mapper, + const RigContourMapProjection& contourMapProjection, + const RigContourMapGrid& contourMapGrid ); + cvf::ref createTextureCoords( const std::vector& values, cvf::ScalarMapper* scalarMapper ) const; private: @@ -104,9 +112,15 @@ private: const RigContourPolygonsTools::ContourPolygons& previousLevel, double tolerance ); + cvf::ref createSingleTexturedQuadPart( const cvf::Vec3dArray& cornerPoints, cvf::ref image, bool transparent ); + static cvf::ref createXYPlaneQuadGeoWithTexCoords( const cvf::Vec3dArray& cornerPoints ); + static cvf::TextureImage* createTexture( const RigContourMapProjection* contourMapProjection, cvf::ScalarMapper* scalarMapper ); + private: caf::PdmPointer m_pdmObject; std::vector> m_labelBoundingBoxes; cvf::ref m_labelEffect; + + cvf::ref m_textureShaderProg; }; diff --git a/ApplicationLibCode/ProjectDataModel/ContourMap/RimContourMapProjection.cpp b/ApplicationLibCode/ProjectDataModel/ContourMap/RimContourMapProjection.cpp index 11df856670..abc7c2aa0b 100644 --- a/ApplicationLibCode/ProjectDataModel/ContourMap/RimContourMapProjection.cpp +++ b/ApplicationLibCode/ProjectDataModel/ContourMap/RimContourMapProjection.cpp @@ -109,6 +109,8 @@ RimContourMapProjection::RimContourMapProjection() CAF_PDM_InitField( &m_showContourLines, "ContourLines", true, "Show Contour Lines" ); CAF_PDM_InitField( &m_showContourLabels, "ContourLabels", true, "Show Contour Labels" ); CAF_PDM_InitField( &m_smoothContourLines, "SmoothContourLines", true, "Smooth Contour Lines" ); + CAF_PDM_InitField( &m_showTextureImage, "ShowImage", true, "Show Texture Image" ); + CAF_PDM_InitField( &m_showTrianglesWithColor, "ShowTrianglesWithColor", false, "Show Triangles with Color" ); auto defaultValue = caf::AppEnum( RimIntersectionFilterEnum::INTERSECT_FILTER_NONE ); CAF_PDM_InitField( &m_valueFilterType, "ValueFilterType", defaultValue, "Value Filter" ); @@ -208,13 +210,16 @@ void RimContourMapProjection::generateGeometryIfNecessary() } } - m_trianglesWithVertexValues = RigContourMapTrianglesGenerator::generateTrianglesWithVertexValues( *m_contourMapGrid, - *m_contourMapProjection, - m_contourPolygons, - contourLevels, - m_contourLevelCumulativeAreas, - discrete, - sampleSpacing() ); + if ( showTrianglesWithColor() ) + { + m_trianglesWithVertexValues = RigContourMapTrianglesGenerator::generateTrianglesWithVertexValues( *m_contourMapGrid, + *m_contourMapProjection, + m_contourPolygons, + contourLevels, + m_contourLevelCumulativeAreas, + discrete, + sampleSpacing() ); + } } progress.setProgress( 100 ); } @@ -268,6 +273,22 @@ bool RimContourMapProjection::showContourLabels() const return m_showContourLabels(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::showImage() const +{ + return m_showTextureImage(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::showTrianglesWithColor() const +{ + return m_showTrianglesWithColor(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -615,6 +636,8 @@ void RimContourMapProjection::defineUiOrdering( QString uiConfigName, caf::PdmUi legendConfig()->uiOrdering( "NumLevelsOnly", *mainGroup ); mainGroup->add( &m_resolution ); + mainGroup->add( &m_showTextureImage ); + mainGroup->add( &m_showTrianglesWithColor ); mainGroup->add( &m_showContourLines ); mainGroup->add( &m_showContourLabels ); m_showContourLabels.uiCapability()->setUiReadOnly( !m_showContourLines() ); diff --git a/ApplicationLibCode/ProjectDataModel/ContourMap/RimContourMapProjection.h b/ApplicationLibCode/ProjectDataModel/ContourMap/RimContourMapProjection.h index 5a1aa7d5c5..b2258198ad 100644 --- a/ApplicationLibCode/ProjectDataModel/ContourMap/RimContourMapProjection.h +++ b/ApplicationLibCode/ProjectDataModel/ContourMap/RimContourMapProjection.h @@ -68,6 +68,8 @@ public: bool showContourLines() const; bool showContourLabels() const; + bool showImage() const; + bool showTrianglesWithColor() const; // k layer filter, only consider kLayers in the given set (0-based index) void useKLayers( std::set kLayers ); @@ -150,6 +152,8 @@ protected: caf::PdmField m_showContourLines; caf::PdmField m_showContourLabels; caf::PdmField m_smoothContourLines; + caf::PdmField m_showTextureImage; + caf::PdmField m_showTrianglesWithColor; caf::PdmField m_oilFloodingType; caf::PdmField m_gasFloodingType; diff --git a/ApplicationLibCode/ProjectDataModel/ContourMap/RimEclipseContourMapView.cpp b/ApplicationLibCode/ProjectDataModel/ContourMap/RimEclipseContourMapView.cpp index 1427da563a..c6f6c8b497 100644 --- a/ApplicationLibCode/ProjectDataModel/ContourMap/RimEclipseContourMapView.cpp +++ b/ApplicationLibCode/ProjectDataModel/ContourMap/RimEclipseContourMapView.cpp @@ -345,12 +345,24 @@ void RimEclipseContourMapView::appendContourMapProjectionToModel() cvf::ref transForm = displayCoordTransform(); - m_contourMapProjectionPartMgr->appendProjectionToModel( contourMapProjectionModelBasicList.p(), - transForm.p(), - m_contourMapProjection->trianglesWithVertexValues(), - *m_contourMapProjection->mapGrid(), - backgroundColor(), - m_contourMapProjection->legendConfig()->scalarMapper() ); + if ( m_contourMapProjection->showTrianglesWithColor() ) + { + m_contourMapProjectionPartMgr->appendProjectionToModel( contourMapProjectionModelBasicList.p(), + transForm.p(), + m_contourMapProjection->trianglesWithVertexValues(), + *m_contourMapProjection->mapGrid(), + backgroundColor(), + m_contourMapProjection->legendConfig()->scalarMapper() ); + } + + if ( m_contourMapProjection->showImage() ) + { + m_contourMapProjectionPartMgr->appendProjectionAsTexturedQuad( contourMapProjectionModelBasicList.p(), + transForm.p(), + m_contourMapProjection->legendConfig()->scalarMapper(), + *m_contourMapProjection->mapProjection(), + *m_contourMapProjection->mapGrid() ); + } contourMapProjectionModelBasicList->updateBoundingBoxesRecursive(); frameScene->addModel( contourMapProjectionModelBasicList.p() ); diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechContourMapView.cpp b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechContourMapView.cpp index 3c5a7a803a..99722f2c9e 100644 --- a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechContourMapView.cpp +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechContourMapView.cpp @@ -313,12 +313,24 @@ void RimGeoMechContourMapView::appendContourMapProjectionToModel() cvf::ref transForm = displayCoordTransform(); - m_contourMapProjectionPartMgr->appendProjectionToModel( contourMapProjectionModelBasicList.p(), - transForm.p(), - m_contourMapProjection->trianglesWithVertexValues(), - *m_contourMapProjection->mapGrid(), - backgroundColor(), - m_contourMapProjection->legendConfig()->scalarMapper() ); + if ( m_contourMapProjection->showTrianglesWithColor() ) + { + m_contourMapProjectionPartMgr->appendProjectionToModel( contourMapProjectionModelBasicList.p(), + transForm.p(), + m_contourMapProjection->trianglesWithVertexValues(), + *m_contourMapProjection->mapGrid(), + backgroundColor(), + m_contourMapProjection->legendConfig()->scalarMapper() ); + } + + if ( m_contourMapProjection->showImage() ) + { + m_contourMapProjectionPartMgr->appendProjectionAsTexturedQuad( contourMapProjectionModelBasicList.p(), + transForm.p(), + m_contourMapProjection->legendConfig()->scalarMapper(), + *m_contourMapProjection->mapProjection(), + *m_contourMapProjection->mapGrid() ); + } contourMapProjectionModelBasicList->updateBoundingBoxesRecursive(); frameScene->addModel( contourMapProjectionModelBasicList.p() );