Skip to content

Commit

Permalink
working version
Browse files Browse the repository at this point in the history
  • Loading branch information
magnesj committed Jan 10, 2025
1 parent 90a1642 commit 3c1e9d8
Show file tree
Hide file tree
Showing 7 changed files with 480 additions and 0 deletions.
2 changes: 2 additions & 0 deletions ApplicationLibCode/Commands/CMakeLists_files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RicNewWellTargetCandidatesGeneratorFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicNewStatisticsContourMapFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicNewStatisticsContourMapViewFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicCreateContourMapPolygonFeature.h
)

set(SOURCE_GROUP_SOURCE_FILES
Expand Down Expand Up @@ -202,6 +203,7 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RicNewWellTargetCandidatesGeneratorFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicNewStatisticsContourMapFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicNewStatisticsContourMapViewFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicCreateContourMapPolygonFeature.cpp
)

if(RESINSIGHT_USE_QT_CHARTS)
Expand Down
190 changes: 190 additions & 0 deletions ApplicationLibCode/Commands/RicCreateContourMapPolygonFeature.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////

#include "RicCreateContourMapPolygonFeature.h"

#include "RiaLogging.h"

#include "RigActiveCellInfo.h"
#include "RigCaseCellResultsData.h"
#include "RigCell.h"
#include "RigContourMapProjection.h"
#include "RigConvexHull.h"
#include "RigMainGrid.h"
#include "RigStatisticsMath.h"

#include "Polygons/RimPolygon.h"
#include "Polygons/RimPolygonCollection.h"
#include "Rim3dOverlayInfoConfig.h"
#include "RimContourMapProjection.h"
#include "RimEclipseCase.h"
#include "RimEclipseCellColors.h"
#include "RimEclipseView.h"
#include "RimOilField.h"
#include "RimProject.h"
#include "RimWellTargetCandidatesGenerator.h"

#include "cafSelectionManager.h"
#include "cvfMath.h"

#include <QAction>

CAF_CMD_SOURCE_INIT( RicCreateContourMapPolygonFeature, "RicCreateContourMapPolygonFeature" );

void exportVectorAsImage( const std::vector<std::vector<int>>& data, const QString& filename )
{
if ( data.empty() || data[0].empty() )
{
qWarning( "Data is empty. Cannot export an image." );
return;
}

// Get dimensions
int height = static_cast<int>( data.size() );
int width = static_cast<int>( data[0].size() );

// Create a QImage
QImage image( width, height, QImage::Format_Grayscale8 );

// Fill QImage with data
for ( int y = 0; y < height; ++y )
{
for ( int x = 0; x < width; ++x )
{
int value = std::clamp( data[y][x] * 255, 0, 255 ); // Ensure value is in [0, 255]
image.setPixel( x, y, qRgb( value, value, value ) ); // Grayscale
}
}

// Save the QImage as a PNG file
if ( !image.save( filename, "PNG" ) )
{
qWarning( "Failed to save image as PNG." );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicCreateContourMapPolygonFeature::onActionTriggered( bool isChecked )
{
auto contourMapProjection = caf::SelectionManager::instance()->selectedItemOfType<RimContourMapProjection>();
if ( !contourMapProjection ) return;

auto rigContourMapProjection = contourMapProjection->mapProjection();
if ( !rigContourMapProjection ) return;

auto vertexSizeIJ = rigContourMapProjection->numberOfVerticesIJ();

/* auto rows = image.size();
auto cols = image[0].size();
int offset = kernelSize / 2;
Matrix dilated( rows, vector<int>( cols, 0 ) );
*/

std::vector<std::vector<int>> image( vertexSizeIJ.x(), std::vector<int>( vertexSizeIJ.y(), 0 ) );

for ( cvf::uint i = 0; i < vertexSizeIJ.x(); i++ )
{
for ( cvf::uint j = 0; j < vertexSizeIJ.y(); j++ )
{
double valueAtVertex = rigContourMapProjection->valueAtVertex( i, j );

if ( !std::isinf( valueAtVertex ) )
{
image[i][j] = 1;
}
else
{
image[i][j] = 0;
}
}
}

{
const QString fileName = "f:/scratch/2025-fault-reactivation/original_image.png";
exportVectorAsImage( image, fileName );
}

auto kernelSize = 7;

auto eroded = RigContourPolygonsTools::erode( image, kernelSize );
{
const QString fileName = "f:/scratch/2025-fault-reactivation/eroded.png";
exportVectorAsImage( eroded, fileName );
}

auto dilated = RigContourPolygonsTools::dilate( eroded, kernelSize );
{
const QString fileName = "f:/scratch/2025-fault-reactivation/dilated.png";
exportVectorAsImage( dilated, fileName );
}

auto dilated2 = RigContourPolygonsTools::dilate( dilated, kernelSize );
{
const QString fileName = "f:/scratch/2025-fault-reactivation/dilated2.png";
exportVectorAsImage( dilated2, fileName );
}

auto boundaryPoints = RigContourPolygonsTools::boundary( dilated );

{
auto xVertexPositions = rigContourMapProjection->xVertexPositions();
auto yVertexPositions = rigContourMapProjection->yVertexPositions();
auto origin3d = rigContourMapProjection->origin3d();

std::vector<cvf::Vec3d> polygonBoundary;

for ( auto [i, j] : boundaryPoints )
{
double x = xVertexPositions.at( i );
double y = yVertexPositions.at( j );
x += origin3d.x();
y += origin3d.y();

polygonBoundary.emplace_back( cvf::Vec3d( x, y, 0.0 ) );

QString message = QString( "Boundary point: x=%1, y=%2" ).arg( x ).arg( y );

RiaLogging::info( message );
}

// Need at least three points to make a polygon
if ( polygonBoundary.size() >= 3 )
{
auto proj = RimProject::current();
auto polygonCollection = proj->activeOilField()->polygonCollection();

auto newPolygon = polygonCollection->appendUserDefinedPolygon();
newPolygon->setPointsInDomainCoords( polygonBoundary );
newPolygon->coordinatesChanged.send();

polygonCollection->uiCapability()->updateAllRequiredEditors();
}
}
}

//--------------------------------------------------------------------------------------------------

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicCreateContourMapPolygonFeature::setupActionLook( QAction* actionToSetup )
{
// actionToSetup->setIcon( QIcon( ":/GeoMechCasePropTable24x24.png" ) );
actionToSetup->setText( "Create Well Target Cluster Polygons" );
}
41 changes: 41 additions & 0 deletions ApplicationLibCode/Commands/RicCreateContourMapPolygonFeature.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////

#pragma once

#include "cafCmdFeature.h"

#include "cvfArray.h"
#include "cvfObject.h"

class RimEclipseCase;
class RimEclipseView;
class RigEclipseResultAddress;
class RigActiveCellInfo;

//==================================================================================================
///
//==================================================================================================
class RicCreateContourMapPolygonFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;

protected:
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
};
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "RimRegularLegendConfig.h"
#include "RimTextAnnotation.h"

#include "cafCmdFeatureMenuBuilder.h"
#include "cafPdmUiDoubleSliderEditor.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafProgressInfo.h"
Expand Down Expand Up @@ -541,6 +542,14 @@ void RimContourMapProjection::initAfterRead()
{
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimContourMapProjection::appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const
{
menuBuilder << "RicCreateContourMapPolygonFeature";
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class RimContourMapProjection : public RimCheckableNamedObject
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
void initAfterRead() override;
void appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const override;

protected:
caf::PdmField<double> m_relativeSampleSpacing;
Expand Down
Loading

0 comments on commit 3c1e9d8

Please sign in to comment.