From ebc805ab652304b0ca9b20b12ad213860eadf383 Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Thu, 17 Oct 2024 09:19:52 +0200 Subject: [PATCH] Refactor: Extractor contour polygon tools. --- .../RivContourMapProjectionPartMgr.cpp | 47 +---- .../RivContourMapProjectionPartMgr.h | 7 +- .../RimContourMapProjection.cpp | 135 +------------ .../RimContourMapProjection.h | 18 +- .../ReservoirDataModel/CMakeLists_files.cmake | 2 + .../RigContourPolygonsTools.cpp | 188 ++++++++++++++++++ .../RigContourPolygonsTools.h | 53 +++++ 7 files changed, 268 insertions(+), 182 deletions(-) create mode 100644 ApplicationLibCode/ReservoirDataModel/RigContourPolygonsTools.cpp create mode 100644 ApplicationLibCode/ReservoirDataModel/RigContourPolygonsTools.h diff --git a/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp b/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp index 62f31799fb..7bd447aa74 100644 --- a/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp +++ b/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp @@ -4,6 +4,7 @@ #include "RiaFontCache.h" #include "RiaWeightedMeanCalculator.h" #include "RigCellGeometryTools.h" +#include "RigContourPolygonsTools.h" #include "RivMeshLinesSourceInfo.h" #include "RivPartPriority.h" #include "RivScalarMapperUtils.h" @@ -409,7 +410,7 @@ std::vector> std::vector tickValues; mapper->majorTickValues( &tickValues ); - const RimContourMapProjection::ContourPolygons* previousLevel = nullptr; + const RigContourPolygonsTools::ContourPolygons* previousLevel = nullptr; for ( int64_t i = (int64_t)m_contourLinePolygons.size() - 1; i > 0; --i ) { cvf::Color3f backgroundColor( mapper->mapToColor( tickValues[i] ) ); @@ -435,7 +436,9 @@ std::vector> const cvf::Vec3d& localVertex2 = m_contourLinePolygons[i][j].vertices[nextVertex]; cvf::Vec3d lineCenter = ( localVertex1 + localVertex2 ) * 0.5; - if ( previousLevel && lineOverlapsWithPreviousContourLevel( lineCenter, previousLevel ) ) + double tolerance = 1.0e-2 * m_contourMapProjection->sampleSpacing(); + + if ( previousLevel && lineOverlapsWithPreviousContourLevel( lineCenter, *previousLevel, tolerance ) ) { continue; } @@ -557,41 +560,9 @@ cvf::ref //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RivContourMapProjectionPartMgr::lineOverlapsWithPreviousContourLevel( const cvf::Vec3d& lineCenter, - const RimContourMapProjection::ContourPolygons* previousLevel ) const +bool RivContourMapProjectionPartMgr::lineOverlapsWithPreviousContourLevel( const cvf::Vec3d& lineCenter, + const RigContourPolygonsTools::ContourPolygons& previousLevel, + double tolerance ) { - const int64_t jump = 50; - CVF_ASSERT( previousLevel ); - double tolerance = 1.0e-2 * m_contourMapProjection->sampleSpacing(); - for ( const RimContourMapProjection::ContourPolygon& edgePolygon : *previousLevel ) - { - std::pair closestIndex( 0, std::numeric_limits::infinity() ); - for ( int64_t i = 0; i < (int64_t)edgePolygon.vertices.size(); i += jump ) - { - const cvf::Vec3d& edgeVertex1 = edgePolygon.vertices[i]; - const cvf::Vec3d& edgeVertex2 = edgePolygon.vertices[( i + 1 ) % edgePolygon.vertices.size()]; - double dist1 = cvf::GeometryTools::linePointSquareDist( edgeVertex1, edgeVertex2, lineCenter ); - if ( dist1 < tolerance ) - { - return true; - } - if ( dist1 < closestIndex.second ) - { - closestIndex = std::make_pair( i, dist1 ); - } - } - for ( int64_t i = std::max( (int64_t)1, closestIndex.first - jump + 1 ); - i < std::min( (int64_t)edgePolygon.vertices.size(), closestIndex.first + jump ); - ++i ) - { - const cvf::Vec3d& edgeVertex1 = edgePolygon.vertices[i]; - const cvf::Vec3d& edgeVertex2 = edgePolygon.vertices[( i + 1 ) % edgePolygon.vertices.size()]; - double dist1 = cvf::GeometryTools::linePointSquareDist( edgeVertex1, edgeVertex2, lineCenter ); - if ( dist1 < tolerance ) - { - return true; - } - } - } - return false; + return RigContourPolygonsTools::lineOverlapsWithContourPolygons( lineCenter, previousLevel, tolerance ); } diff --git a/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.h b/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.h index 70c651cfbc..fe5c45b76e 100644 --- a/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.h +++ b/ApplicationLibCode/ModelVisualization/RivContourMapProjectionPartMgr.h @@ -18,7 +18,7 @@ #pragma once -#include "RimEclipseContourMapProjection.h" +#include "RimContourMapProjection.h" #include "cafDisplayCoordTransform.h" #include "cafPdmPointer.h" @@ -59,8 +59,9 @@ private: const caf::DisplayCoordTransform* displayCoordTransform, std::vector>* labelBBoxes ) const; cvf::ref createPickPointVisDrawable( const caf::DisplayCoordTransform* displayCoordTransform ) const; - bool lineOverlapsWithPreviousContourLevel( const cvf::Vec3d& lineCenter, - const RimContourMapProjection::ContourPolygons* previousLevel ) const; + static bool lineOverlapsWithPreviousContourLevel( const cvf::Vec3d& lineCenter, + const RimContourMapProjection::ContourPolygons& previousLevel, + double tolerance ); private: caf::PdmPointer m_contourMapProjection; diff --git a/ApplicationLibCode/ProjectDataModel/RimContourMapProjection.cpp b/ApplicationLibCode/ProjectDataModel/RimContourMapProjection.cpp index e7a39e9889..8a514febf0 100644 --- a/ApplicationLibCode/ProjectDataModel/RimContourMapProjection.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimContourMapProjection.cpp @@ -1061,18 +1061,21 @@ void RimContourMapProjection::generateContourPolygons() caf::ContourLines::create( m_aggregatedVertexResults, xVertexPositions(), yVertexPositions(), contourLevels ); contourPolygons = std::vector( unorderedLineSegmentsPerLevel.size() ); + const double areaThreshold = 1.5 * ( sampleSpacing() * sampleSpacing() ) / ( sampleSpacingFactor() * sampleSpacingFactor() ); #pragma omp parallel for for ( int i = 0; i < (int)unorderedLineSegmentsPerLevel.size(); ++i ) { - contourPolygons[i] = createContourPolygonsFromLineSegments( unorderedLineSegmentsPerLevel[i], contourLevels[i] ); + contourPolygons[i] = RigContourPolygonsTools::createContourPolygonsFromLineSegments( unorderedLineSegmentsPerLevel[i], + contourLevels[i], + areaThreshold ); if ( m_smoothContourLines() ) { - smoothContourPolygons( &contourPolygons[i], true ); + RigContourPolygonsTools::smoothContourPolygons( contourPolygons[i], true, sampleSpacing() ); } - for ( ContourPolygon& polygon : contourPolygons[i] ) + for ( RigContourPolygonsTools::ContourPolygon& polygon : contourPolygons[i] ) { RigCellGeometryTools::simplifyPolygon( &polygon.vertices, simplifyEpsilon ); } @@ -1086,7 +1089,7 @@ void RimContourMapProjection::generateContourPolygons() { for ( size_t i = 1; i < contourPolygons.size(); ++i ) { - clipContourPolygons(&contourPolygons[i], &contourPolygons[i - 1] ); + RigContourPolygonsTools::clipContourPolygons(&contourPolygons[i], &contourPolygons[i - 1] ); } } */ @@ -1094,7 +1097,7 @@ void RimContourMapProjection::generateContourPolygons() m_contourLevelCumulativeAreas.resize( contourPolygons.size(), 0.0 ); for ( int64_t i = (int64_t)contourPolygons.size() - 1; i >= 0; --i ) { - double levelOuterArea = sumPolygonArea( contourPolygons[i] ); + double levelOuterArea = RigContourPolygonsTools::sumPolygonArea( contourPolygons[i] ); m_contourLevelCumulativeAreas[i] = levelOuterArea; } } @@ -1103,128 +1106,6 @@ void RimContourMapProjection::generateContourPolygons() m_contourPolygons = contourPolygons; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimContourMapProjection::ContourPolygons - RimContourMapProjection::createContourPolygonsFromLineSegments( caf::ContourLines::ListOfLineSegments& unorderedLineSegments, - double contourValue ) -{ - const double areaThreshold = 1.5 * ( sampleSpacing() * sampleSpacing() ) / ( sampleSpacingFactor() * sampleSpacingFactor() ); - - ContourPolygons contourPolygons; - - std::vector> polygons; - RigCellGeometryTools::createPolygonFromLineSegments( unorderedLineSegments, polygons, 1.0e-8 ); - for ( size_t j = 0; j < polygons.size(); ++j ) - { - double signedArea = cvf::GeometryTools::signedAreaPlanarPolygon( cvf::Vec3d::Z_AXIS, polygons[j] ); - ContourPolygon contourPolygon; - contourPolygon.value = contourValue; - if ( signedArea < 0.0 ) - { - contourPolygon.vertices.insert( contourPolygon.vertices.end(), polygons[j].rbegin(), polygons[j].rend() ); - } - else - { - contourPolygon.vertices = polygons[j]; - } - - contourPolygon.area = cvf::GeometryTools::signedAreaPlanarPolygon( cvf::Vec3d::Z_AXIS, contourPolygon.vertices ); - if ( contourPolygon.area > areaThreshold ) - { - for ( const cvf::Vec3d& vertex : contourPolygon.vertices ) - { - contourPolygon.bbox.add( vertex ); - } - contourPolygons.push_back( contourPolygon ); - } - } - return contourPolygons; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::smoothContourPolygons( ContourPolygons* contourPolygons, bool favourExpansion ) -{ - CVF_ASSERT( contourPolygons ); - for ( size_t i = 0; i < contourPolygons->size(); ++i ) - { - ContourPolygon& polygon = contourPolygons->at( i ); - - for ( size_t n = 0; n < 20; ++n ) - { - std::vector newVertices; - newVertices.resize( polygon.vertices.size() ); - double maxChange = 0.0; - for ( size_t j = 0; j < polygon.vertices.size(); ++j ) - { - cvf::Vec3d vm1 = polygon.vertices.back(); - cvf::Vec3d v = polygon.vertices[j]; - cvf::Vec3d vp1 = polygon.vertices.front(); - if ( j > 0u ) - { - vm1 = polygon.vertices[j - 1]; - } - if ( j < polygon.vertices.size() - 1 ) - { - vp1 = polygon.vertices[j + 1]; - } - // Only expand. - cvf::Vec3d modifiedVertex = 0.5 * ( v + 0.5 * ( vm1 + vp1 ) ); - cvf::Vec3d delta = modifiedVertex - v; - cvf::Vec3d tangent3d = vp1 - vm1; - cvf::Vec2d tangent2d( tangent3d.x(), tangent3d.y() ); - cvf::Vec3d norm3d( tangent2d.getNormalized().perpendicularVector() ); - if ( delta * norm3d > 0 && favourExpansion ) - { - // Normal is always inwards facing so a positive dot product means inward movement - // Favour expansion rather than contraction by only contracting by a fraction. - // The fraction is empirically found to give a decent result. - modifiedVertex = v + 0.2 * delta; - } - newVertices[j] = modifiedVertex; - maxChange = std::max( maxChange, ( modifiedVertex - v ).length() ); - } - polygon.vertices.swap( newVertices ); - if ( maxChange < sampleSpacing() * 1.0e-2 ) break; - } - } -} - -void RimContourMapProjection::clipContourPolygons( ContourPolygons* contourPolygons, const ContourPolygons* clipBy ) -{ - CVF_ASSERT( clipBy ); - for ( size_t i = 0; i < contourPolygons->size(); ++i ) - { - ContourPolygon& polygon = contourPolygons->at( i ); - for ( size_t j = 0; j < clipBy->size(); ++j ) - { - std::vector> intersections = - RigCellGeometryTools::intersectionWithPolygon( polygon.vertices, clipBy->at( j ).vertices ); - if ( !intersections.empty() ) - { - polygon.vertices = intersections.front(); - polygon.area = std::abs( cvf::GeometryTools::signedAreaPlanarPolygon( cvf::Vec3d::Z_AXIS, polygon.vertices ) ); - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RimContourMapProjection::sumPolygonArea( const ContourPolygons& contourPolygons ) -{ - double sumArea = 0.0; - for ( const ContourPolygon& polygon : contourPolygons ) - { - sumArea += polygon.area; - } - return sumArea; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/RimContourMapProjection.h b/ApplicationLibCode/ProjectDataModel/RimContourMapProjection.h index 868cfdfc63..08ae48c18b 100644 --- a/ApplicationLibCode/ProjectDataModel/RimContourMapProjection.h +++ b/ApplicationLibCode/ProjectDataModel/RimContourMapProjection.h @@ -20,7 +20,8 @@ #include "RimCheckableNamedObject.h" -#include "cafContourLines.h" +#include "RigContourPolygonsTools.h" + #include "cafPdmField.h" #include "cafPdmObject.h" @@ -43,14 +44,6 @@ class RimContourMapProjection : public RimCheckableNamedObject public: using CellIndexAndResult = std::pair; - struct ContourPolygon - { - std::vector vertices; - double value; - double area; - cvf::BoundingBox bbox; - }; - enum ResultAggregationEnum { RESULTS_TOP_VALUE, @@ -66,7 +59,7 @@ public: RESULTS_HC_COLUMN }; using ResultAggregation = caf::AppEnum; - using ContourPolygons = std::vector; + using ContourPolygons = std::vector; RimContourMapProjection(); ~RimContourMapProjection() override; @@ -164,10 +157,7 @@ protected: void generateVertexResults(); void generateTrianglesWithVertexValues(); void generateContourPolygons(); - ContourPolygons createContourPolygonsFromLineSegments( caf::ContourLines::ListOfLineSegments& unorderedLineSegments, double contourValue ); - void smoothContourPolygons( ContourPolygons* contourPolygons, bool favourExpansion ); - void clipContourPolygons( ContourPolygons* contourPolygons, const ContourPolygons* clipBy ); - static double sumPolygonArea( const ContourPolygons& contourPolygons ); + static double sumTriangleAreas( const std::vector& triangles ); std::vector cellOverlapVolumesAndResults( const cvf::Vec2d& globalPos2d, diff --git a/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake index be2bd970b6..8e9b8bd8cd 100644 --- a/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake +++ b/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake @@ -103,6 +103,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RigOsduWellLogData.h ${CMAKE_CURRENT_LIST_DIR}/RigWellTargetCandidatesGenerator.h ${CMAKE_CURRENT_LIST_DIR}/RigContourMapGrid.h + ${CMAKE_CURRENT_LIST_DIR}/RigContourPolygonsTools.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -204,6 +205,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RigOsduWellLogData.cpp ${CMAKE_CURRENT_LIST_DIR}/RigWellTargetCandidatesGenerator.cpp ${CMAKE_CURRENT_LIST_DIR}/RigContourMapGrid.cpp + ${CMAKE_CURRENT_LIST_DIR}/RigContourPolygonsTools.cpp ) list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES}) diff --git a/ApplicationLibCode/ReservoirDataModel/RigContourPolygonsTools.cpp b/ApplicationLibCode/ReservoirDataModel/RigContourPolygonsTools.cpp new file mode 100644 index 0000000000..e859c873d7 --- /dev/null +++ b/ApplicationLibCode/ReservoirDataModel/RigContourPolygonsTools.cpp @@ -0,0 +1,188 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024- 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 "RigContourPolygonsTools.h" + +#include "RigCellGeometryTools.h" + +#include "cafContourLines.h" + +#include "cvfGeometryTools.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigContourPolygonsTools::ContourPolygons + RigContourPolygonsTools::createContourPolygonsFromLineSegments( caf::ContourLines::ListOfLineSegments& unorderedLineSegments, + double contourValue, + double areaThreshold ) +{ + ContourPolygons contourPolygons; + + std::vector> polygons; + RigCellGeometryTools::createPolygonFromLineSegments( unorderedLineSegments, polygons, 1.0e-8 ); + for ( size_t j = 0; j < polygons.size(); ++j ) + { + double signedArea = cvf::GeometryTools::signedAreaPlanarPolygon( cvf::Vec3d::Z_AXIS, polygons[j] ); + ContourPolygon contourPolygon; + contourPolygon.value = contourValue; + if ( signedArea < 0.0 ) + { + contourPolygon.vertices.insert( contourPolygon.vertices.end(), polygons[j].rbegin(), polygons[j].rend() ); + } + else + { + contourPolygon.vertices = polygons[j]; + } + + contourPolygon.area = cvf::GeometryTools::signedAreaPlanarPolygon( cvf::Vec3d::Z_AXIS, contourPolygon.vertices ); + if ( contourPolygon.area > areaThreshold ) + { + for ( const cvf::Vec3d& vertex : contourPolygon.vertices ) + { + contourPolygon.bbox.add( vertex ); + } + contourPolygons.push_back( contourPolygon ); + } + } + return contourPolygons; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigContourPolygonsTools::smoothContourPolygons( ContourPolygons& contourPolygons, bool favourExpansion, double sampleSpacing ) +{ + for ( RigContourPolygonsTools::ContourPolygon& polygon : contourPolygons ) + { + for ( size_t n = 0; n < 20; ++n ) + { + std::vector newVertices; + newVertices.resize( polygon.vertices.size() ); + double maxChange = 0.0; + for ( size_t j = 0; j < polygon.vertices.size(); ++j ) + { + cvf::Vec3d vm1 = polygon.vertices.back(); + cvf::Vec3d v = polygon.vertices[j]; + cvf::Vec3d vp1 = polygon.vertices.front(); + if ( j > 0u ) + { + vm1 = polygon.vertices[j - 1]; + } + if ( j < polygon.vertices.size() - 1 ) + { + vp1 = polygon.vertices[j + 1]; + } + // Only expand. + cvf::Vec3d modifiedVertex = 0.5 * ( v + 0.5 * ( vm1 + vp1 ) ); + cvf::Vec3d delta = modifiedVertex - v; + cvf::Vec3d tangent3d = vp1 - vm1; + cvf::Vec2d tangent2d( tangent3d.x(), tangent3d.y() ); + cvf::Vec3d norm3d( tangent2d.getNormalized().perpendicularVector() ); + if ( delta * norm3d > 0 && favourExpansion ) + { + // Normal is always inwards facing so a positive dot product means inward movement + // Favour expansion rather than contraction by only contracting by a fraction. + // The fraction is empirically found to give a decent result. + modifiedVertex = v + 0.2 * delta; + } + newVertices[j] = modifiedVertex; + maxChange = std::max( maxChange, ( modifiedVertex - v ).length() ); + } + polygon.vertices.swap( newVertices ); + if ( maxChange < sampleSpacing * 1.0e-2 ) break; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigContourPolygonsTools::clipContourPolygons( ContourPolygons& contourPolygons, const ContourPolygons& clipBy ) +{ + for ( RigContourPolygonsTools::ContourPolygon& polygon : contourPolygons ) + { + for ( const RigContourPolygonsTools::ContourPolygon& clipPolygon : contourPolygons ) + { + std::vector> intersections = + RigCellGeometryTools::intersectionWithPolygon( polygon.vertices, clipPolygon.vertices ); + if ( !intersections.empty() ) + { + polygon.vertices = intersections.front(); + polygon.area = std::abs( cvf::GeometryTools::signedAreaPlanarPolygon( cvf::Vec3d::Z_AXIS, polygon.vertices ) ); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigContourPolygonsTools::sumPolygonArea( const ContourPolygons& contourPolygons ) +{ + double sumArea = 0.0; + for ( const ContourPolygon& polygon : contourPolygons ) + { + sumArea += polygon.area; + } + return sumArea; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigContourPolygonsTools::lineOverlapsWithContourPolygons( const cvf::Vec3d& lineCenter, + const RigContourPolygonsTools::ContourPolygons& contourPolygons, + double tolerance ) +{ + const int64_t jump = 50; + for ( const RigContourPolygonsTools::ContourPolygon& edgePolygon : contourPolygons ) + { + std::pair closestIndex( 0, std::numeric_limits::infinity() ); + for ( int64_t i = 0; i < (int64_t)edgePolygon.vertices.size(); i += jump ) + { + const cvf::Vec3d& edgeVertex1 = edgePolygon.vertices[i]; + const cvf::Vec3d& edgeVertex2 = edgePolygon.vertices[( i + 1 ) % edgePolygon.vertices.size()]; + double dist1 = cvf::GeometryTools::linePointSquareDist( edgeVertex1, edgeVertex2, lineCenter ); + if ( dist1 < tolerance ) + { + return true; + } + if ( dist1 < closestIndex.second ) + { + closestIndex = std::make_pair( i, dist1 ); + } + } + + for ( int64_t i = std::max( (int64_t)1, closestIndex.first - jump + 1 ); + i < std::min( (int64_t)edgePolygon.vertices.size(), closestIndex.first + jump ); + ++i ) + { + const cvf::Vec3d& edgeVertex1 = edgePolygon.vertices[i]; + const cvf::Vec3d& edgeVertex2 = edgePolygon.vertices[( i + 1 ) % edgePolygon.vertices.size()]; + double dist1 = cvf::GeometryTools::linePointSquareDist( edgeVertex1, edgeVertex2, lineCenter ); + if ( dist1 < tolerance ) + { + return true; + } + } + } + return false; +} diff --git a/ApplicationLibCode/ReservoirDataModel/RigContourPolygonsTools.h b/ApplicationLibCode/ReservoirDataModel/RigContourPolygonsTools.h new file mode 100644 index 0000000000..c767dcd47a --- /dev/null +++ b/ApplicationLibCode/ReservoirDataModel/RigContourPolygonsTools.h @@ -0,0 +1,53 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024- 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafContourLines.h" + +#include "cvfBoundingBox.h" + +class RigContourMapGrid; +class RimGridView; +class RimRegularLegendConfig; + +//================================================================================================== +/// +/// +//================================================================================================== +class RigContourPolygonsTools +{ +public: + struct ContourPolygon + { + std::vector vertices; + double value; + double area; + cvf::BoundingBox bbox; + }; + + using ContourPolygons = std::vector; + + static ContourPolygons createContourPolygonsFromLineSegments( caf::ContourLines::ListOfLineSegments& unorderedLineSegments, + double contourValue, + double areaThreshold ); + static void smoothContourPolygons( ContourPolygons& contourPolygons, bool favourExpansion, double sampleSpacing ); + static void clipContourPolygons( ContourPolygons& contourPolygons, const ContourPolygons& clipBy ); + static double sumPolygonArea( const ContourPolygons& contourPolygons ); + static bool lineOverlapsWithContourPolygons( const cvf::Vec3d& lineCenter, const ContourPolygons& contourPolygons, double tolerance ); +};