///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2026- Equinor ASA // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. // // See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RivIjkIntersectionPartMgr.h" #include "Rim3dView.h" #include "RimEclipseView.h" #include "RimIjkIntersection.h" #include "RivEclipseIntersectionGrid.h" #include "RivIjkIntersectionSourceInfo.h" #include "RivIntersectionGeometryGeneratorInterface.h" #include "RivIntersectionHexGridInterface.h" #include "RivIntersectionResultsColoringTools.h" #include "RivMeshLinesSourceInfo.h" #include "RivPartPriority.h" #include "RivScalarMapperUtils.h" #include "RivSurfaceIntersectionCurveTools.h" #include "cafEffectGenerator.h" #include "cvfDrawableGeo.h" #include "cvfModelBasicList.h" #include "cvfPart.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RivIjkIntersectionPartMgr::RivIjkIntersectionPartMgr( RimIjkIntersection* intersection ) : m_rimIntersection( intersection ) , m_defaultColor( cvf::Color3::WHITE ) { CAF_ASSERT( m_rimIntersection ); m_intersectionFacesTextureCoords = new cvf::Vec2fArray; // The IJK indices refer to the view's main grid, so the hex grid must be built from the same grid as mainGrid(). // RimIntersection::createHexGridInterface() is not used here, as it returns the grid of a different case when a // separate result definition is active. cvf::ref hexGrid; auto eclipseView = intersection->firstAncestorOrThisOfType(); if ( eclipseView && eclipseView->mainGrid() ) { hexGrid = new RivEclipseIntersectionGrid( eclipseView->mainGrid(), eclipseView->currentActiveCellInfo(), intersection->isInactiveCellsVisible() ); } m_intersectionGenerator = new RivIjkIntersectionGeometryGenerator( m_rimIntersection, hexGrid.p(), intersection->mainGrid() ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivIjkIntersectionPartMgr::applySingleColorEffect() { m_defaultColor = cvf::Color3f::OLIVE; updatePartEffect(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivIjkIntersectionPartMgr::updateCellResultColor( int timeStepIndex ) { RivIntersectionResultsColoringTools::calculateIntersectionResultColors( timeStepIndex, true, m_rimIntersection, m_intersectionGenerator.p(), nullptr, nullptr, m_intersectionFaces.p(), m_intersectionFacesTextureCoords.p() ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivIjkIntersectionPartMgr::generatePartGeometry( cvf::UByteArray* visibleCells, cvf::Transform* scaleTransform ) { bool useBufferObjects = true; // Surface geometry { cvf::ref geo = m_intersectionGenerator->generateSurface( visibleCells ); if ( geo.notNull() ) { geo->computeNormals(); if ( useBufferObjects ) { geo->setRenderMode( cvf::DrawableGeo::BUFFER_OBJECT ); } cvf::ref part = new cvf::Part; part->setName( "Intersection IJK" ); part->setDrawable( geo.p() ); // Set mapping from triangle face index to cell index cvf::ref si = new RivIjkIntersectionSourceInfo( m_intersectionGenerator.p() ); part->setSourceInfo( si.p() ); part->updateBoundingBox(); part->setEnableMask( intersectionCellFaceBit ); part->setPriority( RivPartPriority::PartType::Intersection ); m_intersectionFaces = part; } } // Mesh geometry { cvf::ref geoMesh = m_intersectionGenerator->createMeshDrawable(); if ( geoMesh.notNull() ) { if ( useBufferObjects ) { geoMesh->setRenderMode( cvf::DrawableGeo::BUFFER_OBJECT ); } cvf::ref part = new cvf::Part; part->setName( "Intersection IJK mesh" ); part->setDrawable( geoMesh.p() ); part->updateBoundingBox(); part->setEnableMask( intersectionCellMeshBit ); part->setPriority( RivPartPriority::PartType::MeshLines ); part->setSourceInfo( new RivMeshLinesSourceInfo( m_rimIntersection ) ); m_intersectionGridLines = part; } } if ( scaleTransform ) m_annotationParts = RivSurfaceIntersectionCurveTools::createAnnotationParts( m_rimIntersection, *scaleTransform ); updatePartEffect(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivIjkIntersectionPartMgr::updatePartEffect() { caf::SurfaceEffectGenerator geometryEffgen( m_defaultColor, caf::PO_1 ); cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); if ( m_intersectionFaces.notNull() ) { m_intersectionFaces->setEffect( geometryOnlyEffect.p() ); } cvf::ref eff; caf::MeshEffectGenerator meshEffGen( cvf::Color3::WHITE ); eff = meshEffGen.generateCachedEffect(); if ( m_intersectionGridLines.notNull() ) { m_intersectionGridLines->setEffect( eff.p() ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivIjkIntersectionPartMgr::appendNativeIntersectionFacesToModel( cvf::ModelBasicList* model, cvf::Transform* scaleTransform ) { if ( m_intersectionFaces.notNull() ) { m_intersectionFaces->setTransform( scaleTransform ); model->addPart( m_intersectionFaces.p() ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivIjkIntersectionPartMgr::appendMeshLinePartsToModel( cvf::ModelBasicList* model, cvf::Transform* scaleTransform ) { if ( m_intersectionGridLines.notNull() ) { m_intersectionGridLines->setTransform( scaleTransform ); model->addPart( m_intersectionGridLines.p() ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivIjkIntersectionPartMgr::appendAnnotationPartsToModel( cvf::ModelBasicList* model, cvf::Transform* scaleTransform ) { for ( size_t i = 0; i < m_annotationParts.size(); i++ ) { m_annotationParts[i]->setTransform( scaleTransform ); model->addPart( m_annotationParts.at( i ) ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const RivIntersectionGeometryGeneratorInterface* RivIjkIntersectionPartMgr::intersectionGeometryGenerator() const { if ( m_intersectionGenerator.notNull() ) return m_intersectionGenerator.p(); return nullptr; }