From 319d459d130c72a59fd41c87f909ee67541e46bf Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 20 Feb 2025 09:02:31 +0100 Subject: [PATCH] Prototype for use of texture on quad --- .../RivContourMapProjectionPartMgr.cpp | 219 ++++++++++++++++++ .../RivContourMapProjectionPartMgr.h | 16 ++ .../ContourMap/RimContourMapProjection.cpp | 37 ++- .../ContourMap/RimContourMapProjection.h | 4 + .../ContourMap/RimEclipseContourMapView.cpp | 30 ++- 5 files changed, 293 insertions(+), 13 deletions(-) diff --git a/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp b/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp index 77ceca1018..8fcbe94cd6 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(); } //-------------------------------------------------------------------------------------------------- @@ -102,6 +117,49 @@ void RivContourMapProjectionPartMgr::appendPickPointVisToModel( cvf::ModelBasicL } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +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 ); + } + + // Texture image and part can be cached for better performance + 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() ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -585,3 +643,164 @@ bool RivContourMapProjectionPartMgr::lineOverlapsWithPreviousContourLevel( const { return RigContourPolygonsTools::lineOverlapsWithContourPolygons( lineCenter, previousLevel, tolerance ); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +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 : { 0, 1, 2, 0, 2, 3 } ) + { + 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 ); + geo->computeNormals(); + + cvf::ref eff = new cvf::Effect; + bool surfaceEffect = false; + if ( surfaceEffect ) + { + caf::SurfaceEffectGenerator geometryEffgen( cvf::Color3f::YELLOW, caf::PO_1 ); + eff = geometryEffgen.generateCachedEffect(); + } + else + { + 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" ); + + 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; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QImage RivContourMapProjectionPartMgr::createImage( const RigContourMapProjection* contourMapProjection, cvf::ScalarMapper* scalarMapper ) +{ + if ( !contourMapProjection || !scalarMapper ) return {}; + + auto vertexSizeIJ = contourMapProjection->numberOfVerticesIJ(); + int width = static_cast( vertexSizeIJ.x() ); + int height = static_cast( vertexSizeIJ.y() ); + + QImage image( width, height, QImage::Format_ARGB32 ); + + auto filteredValues = contourMapProjection->aggregatedVertexResultsFiltered(); + for ( int y = 0; y < height; ++y ) + { + for ( int x = 0; x < width; ++x ) + { + auto index = contourMapProjection->vertexIndex( x, y ); + double valueAtVertex = filteredValues[index]; + + auto color = scalarMapper->mapToColor( valueAtVertex ); + + const int transparency = 255; + image.setPixel( x, height - y - 1, qRgba( color.r(), color.g(), color.b(), transparency ) ); + } + } + + return image; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::TextureImage* RivContourMapProjectionPartMgr::createTexture( const RigContourMapProjection* contourMapProjection, + cvf::ScalarMapper* scalarMapper ) +{ + if ( !contourMapProjection || !scalarMapper ) return {}; + + 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 = 0; + if ( valueAtVertex != std::numeric_limits::infinity() ) + { + transparency = 255; + } + + textureImage->setPixel( x, y, cvf::Color4ub( color, transparency ) ); + } + } + + return textureImage; +} diff --git a/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.h b/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.h index 8812cbf6b1..24d28ae80a 100644 --- a/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.h +++ b/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.h @@ -33,6 +33,7 @@ #include "cvfVector4.h" class RigContourMapGrid; +class RigContourMapProjection; namespace cvf { @@ -41,6 +42,7 @@ class ScalarMapper; class Color3f; class ModelBasicList; class Part; +class TextureImage; } // namespace cvf class RivContourMapProjectionPartMgr : public cvf::Object @@ -71,6 +73,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: @@ -105,9 +113,17 @@ private: const RigContourPolygonsTools::ContourPolygons& previousLevel, double tolerance ); + // Extracted some code from RivTexturePartMgr. Consider reuse more code. + cvf::ref createSingleTexturedQuadPart( const cvf::Vec3dArray& cornerPoints, cvf::ref image, bool transparent ); + static cvf::ref createXYPlaneQuadGeoWithTexCoords( const cvf::Vec3dArray& cornerPoints ); + static QImage createImage( const RigContourMapProjection* contourMapProjection, cvf::ScalarMapper* scalarMapper ); + 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 20a05176ef..df85392040 100644 --- a/ApplicationLibCode/ProjectDataModel/ContourMap/RimContourMapProjection.cpp +++ b/ApplicationLibCode/ProjectDataModel/ContourMap/RimContourMapProjection.cpp @@ -110,6 +110,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", false, "Show Texture Image" ); + CAF_PDM_InitField( &m_showTrianglesWithColor, "ShowTrianglesWithColor", true, "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 dad0e62d5f..5dfdf947e8 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..9a9d06a548 100644 --- a/ApplicationLibCode/ProjectDataModel/ContourMap/RimEclipseContourMapView.cpp +++ b/ApplicationLibCode/ProjectDataModel/ContourMap/RimEclipseContourMapView.cpp @@ -345,12 +345,30 @@ 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() ) + { + /* + auto image = RicCreateContourMapPolygonTools::createImage( m_contourMapProjection->mapProjection(), + m_contourMapProjection->legendConfig()->scalarMapper() + ); QString fileName = "f:/scratch/contour-map.png"; image.save( fileName ); + */ + + m_contourMapProjectionPartMgr->appendProjectionAsTexturedQuad( contourMapProjectionModelBasicList.p(), + transForm.p(), + m_contourMapProjection->legendConfig()->scalarMapper(), + *m_contourMapProjection->mapProjection(), + *m_contourMapProjection->mapGrid() ); + } contourMapProjectionModelBasicList->updateBoundingBoxesRecursive(); frameScene->addModel( contourMapProjectionModelBasicList.p() );