mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Add basic support for calculating and showing seismic difference (#10377)
* Add basic support for calculating and showing seismic difference
This commit is contained in:
parent
91762aaeb1
commit
803b67506a
@ -273,6 +273,7 @@
|
||||
<file>DataVectorCalculated.svg</file>
|
||||
<file>open-text-editor.svg</file>
|
||||
<file>Seismic16x16.png</file>
|
||||
<file>SeismicDelta16x16.png</file>
|
||||
<file>Fullscreen.png</file>
|
||||
<file>plot-template-standard.svg</file>
|
||||
<file>plot-template-ensemble.svg</file>
|
||||
|
BIN
ApplicationExeCode/Resources/SeismicDelta16x16.png
Normal file
BIN
ApplicationExeCode/Resources/SeismicDelta16x16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 952 B |
@ -7,6 +7,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewPolylineSeismicSectionFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewWellpathSeismicSectionFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicSeismicSectionFromIntersectionFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewSeismicDifferenceFeature.h
|
||||
)
|
||||
|
||||
set(SOURCE_GROUP_SOURCE_FILES
|
||||
@ -18,6 +19,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewPolylineSeismicSectionFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewWellpathSeismicSectionFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicSeismicSectionFromIntersectionFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewSeismicDifferenceFeature.cpp
|
||||
)
|
||||
|
||||
list(APPEND COMMAND_CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
|
||||
|
@ -75,7 +75,7 @@ void RicImportSeismicFeature::onActionTriggered( bool isChecked )
|
||||
|
||||
if ( !seisColl ) return;
|
||||
|
||||
RimSeismicData* newData = seisColl->importSeismicFromFile( fileName );
|
||||
RimSeismicDataInterface* newData = seisColl->importSeismicFromFile( fileName );
|
||||
|
||||
// workaround to make tree selection work, otherwise "Cell Results" gets selected for some reason
|
||||
QApplication::processEvents();
|
||||
|
@ -0,0 +1,108 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2023 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 "RicNewSeismicDifferenceFeature.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
|
||||
#include "RimOilField.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSeismicData.h"
|
||||
#include "RimSeismicDataCollection.h"
|
||||
|
||||
#include "Riu3DMainWindowTools.h"
|
||||
|
||||
#include "cafPdmUiPropertyViewDialog.h"
|
||||
#include "cafSelectionManagerTools.h"
|
||||
#include "cafUtils.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QMessageBox>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicNewSeismicDifferenceFeature, "RicNewSeismicDifferenceFeature" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicNewSeismicDifferenceFeature::isCommandEnabled()
|
||||
{
|
||||
auto size = selectedSeismic().size();
|
||||
return size == 2;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicNewSeismicDifferenceFeature::onActionTriggered( bool isChecked )
|
||||
{
|
||||
auto proj = RimProject::current();
|
||||
auto& seisColl = proj->activeOilField()->seismicCollection();
|
||||
if ( !seisColl ) return;
|
||||
|
||||
auto seismicInput = selectedSeismic();
|
||||
if ( seismicInput.size() != 2 )
|
||||
{
|
||||
QString warning = "The selected seismic data grids do not match. Cannot create seismic difference data.";
|
||||
QMessageBox::warning( nullptr, "Invalid input.", warning );
|
||||
return;
|
||||
}
|
||||
|
||||
RimSeismicDataInterface* newData = seisColl->createDifferenceSeismicData( seismicInput[0], seismicInput[1] );
|
||||
|
||||
// workaround to make tree selection work, otherwise "Cell Results" gets selected for some reason
|
||||
QApplication::processEvents();
|
||||
|
||||
if ( newData )
|
||||
{
|
||||
Riu3DMainWindowTools::selectAsCurrentItem( newData );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicNewSeismicDifferenceFeature::setupActionLook( QAction* actionToSetup )
|
||||
{
|
||||
actionToSetup->setIcon( QIcon( ":/Seismic16x16.png" ) );
|
||||
actionToSetup->setText( "Create Seismic Difference" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimSeismicData*> RicNewSeismicDifferenceFeature::selectedSeismic()
|
||||
{
|
||||
std::vector<caf::PdmUiItem*> uiItems;
|
||||
caf::SelectionManager::instance()->selectedItems( uiItems );
|
||||
|
||||
if ( uiItems.size() != 2 ) return {};
|
||||
|
||||
std::vector<RimSeismicData*> seismicItems;
|
||||
|
||||
RimSeismicData* seismic1 = dynamic_cast<RimSeismicData*>( uiItems[0] );
|
||||
RimSeismicData* seismic2 = dynamic_cast<RimSeismicData*>( uiItems[1] );
|
||||
|
||||
if ( seismic1 == nullptr ) return {};
|
||||
if ( seismic2 == nullptr ) return {};
|
||||
|
||||
if ( !seismic1->gridIsEqual( seismic2 ) ) return {};
|
||||
|
||||
seismicItems.push_back( seismic1 );
|
||||
seismicItems.push_back( seismic2 );
|
||||
return seismicItems;
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2023 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"
|
||||
|
||||
class RimSeismicData;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicNewSeismicDifferenceFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
protected:
|
||||
bool isCommandEnabled() override;
|
||||
void onActionTriggered( bool isChecked ) override;
|
||||
void setupActionLook( QAction* actionToSetup ) override;
|
||||
|
||||
private:
|
||||
std::vector<RimSeismicData*> selectedSeismic();
|
||||
};
|
@ -249,15 +249,24 @@ void RifOpenVDSReader::histogramData( std::vector<double>& xvals, std::vector<do
|
||||
|
||||
auto accessManager = OpenVDS::GetAccessManager( m_handle );
|
||||
|
||||
auto request = accessManager.RequestVolumeSubset<float>( buffer.data(),
|
||||
buffer.size() * sizeof( float ),
|
||||
OpenVDS::Dimensions_012,
|
||||
0,
|
||||
m_dataChannelToUse,
|
||||
voxelMin,
|
||||
voxelMax );
|
||||
bool success = false;
|
||||
|
||||
try
|
||||
{
|
||||
auto request = accessManager.RequestVolumeSubset<float>( buffer.data(),
|
||||
buffer.size() * sizeof( float ),
|
||||
OpenVDS::Dimensions_012,
|
||||
0,
|
||||
m_dataChannelToUse,
|
||||
voxelMin,
|
||||
voxelMax );
|
||||
|
||||
success = request->WaitForCompletion();
|
||||
}
|
||||
catch ( const std::exception& )
|
||||
{
|
||||
}
|
||||
|
||||
bool success = request->WaitForCompletion();
|
||||
if ( success )
|
||||
{
|
||||
auto chanDesc = m_layout->GetChannelDescriptor( m_dataChannelToUse );
|
||||
@ -460,15 +469,24 @@ std::shared_ptr<ZGYAccess::SeismicSliceData>
|
||||
|
||||
auto accessManager = OpenVDS::GetAccessManager( m_handle );
|
||||
|
||||
auto request = accessManager.RequestVolumeSubset<float>( retData->values(),
|
||||
totalSize * sizeof( float ),
|
||||
OpenVDS::Dimensions_012,
|
||||
0,
|
||||
m_dataChannelToUse,
|
||||
voxelMin,
|
||||
voxelMax );
|
||||
bool success = false;
|
||||
|
||||
try
|
||||
{
|
||||
auto request = accessManager.RequestVolumeSubset<float>( retData->values(),
|
||||
totalSize * sizeof( float ),
|
||||
OpenVDS::Dimensions_012,
|
||||
0,
|
||||
m_dataChannelToUse,
|
||||
voxelMin,
|
||||
voxelMax );
|
||||
|
||||
success = request->WaitForCompletion();
|
||||
}
|
||||
catch ( const std::exception& )
|
||||
{
|
||||
}
|
||||
|
||||
bool success = request->WaitForCompletion();
|
||||
if ( !success ) retData.reset();
|
||||
|
||||
return retData;
|
||||
@ -503,15 +521,24 @@ std::shared_ptr<ZGYAccess::SeismicSliceData> RifOpenVDSReader::trace( int inline
|
||||
|
||||
auto accessManager = OpenVDS::GetAccessManager( m_handle );
|
||||
|
||||
auto request = accessManager.RequestVolumeSubset<float>( retData->values(),
|
||||
zSize * sizeof( float ),
|
||||
OpenVDS::Dimensions_012,
|
||||
0,
|
||||
m_dataChannelToUse,
|
||||
voxelMin,
|
||||
voxelMax );
|
||||
bool success = false;
|
||||
|
||||
try
|
||||
{
|
||||
auto request = accessManager.RequestVolumeSubset<float>( retData->values(),
|
||||
zSize * sizeof( float ),
|
||||
OpenVDS::Dimensions_012,
|
||||
0,
|
||||
m_dataChannelToUse,
|
||||
voxelMin,
|
||||
voxelMax );
|
||||
|
||||
success = request->WaitForCompletion();
|
||||
}
|
||||
catch ( const std::exception& )
|
||||
{
|
||||
}
|
||||
|
||||
bool success = request->WaitForCompletion();
|
||||
if ( !success ) retData.reset();
|
||||
|
||||
return retData;
|
||||
|
@ -113,6 +113,7 @@
|
||||
#include "RimRftPlotCollection.h"
|
||||
#include "RimSaturationPressurePlotCollection.h"
|
||||
#include "RimScriptCollection.h"
|
||||
#include "RimSeismicData.h"
|
||||
#include "RimSeismicDataCollection.h"
|
||||
#include "RimSeismicSectionCollection.h"
|
||||
#include "RimSimWellFracture.h"
|
||||
@ -1242,6 +1243,10 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
|
||||
menuBuilder << "RicAsciiExportSummaryPlotFeature";
|
||||
}
|
||||
}
|
||||
else if ( dynamic_cast<RimSeismicData*>( firstUiItem ) )
|
||||
{
|
||||
menuBuilder << "RicNewSeismicDifferenceFeature";
|
||||
}
|
||||
else if ( dynamic_cast<RimWellLogPlot*>( firstUiItem ) )
|
||||
{
|
||||
menuBuilder << "RicAsciiExportWellLogPlotFeature";
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "RimProject.h"
|
||||
#include "RimSeismicData.h"
|
||||
#include "RimSeismicDataCollection.h"
|
||||
#include "RimSeismicDifferenceData.h"
|
||||
#include "RimWellLogFile.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCollection.h"
|
||||
@ -376,7 +377,26 @@ void RimTools::geoMechCaseOptionItems( QList<caf::PdmOptionItemInfo>* options )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTools::seismicDataOptionItems( QList<caf::PdmOptionItemInfo>* options, cvf::BoundingBox worldBBox )
|
||||
void RimTools::seismicDataOptionItems( QList<caf::PdmOptionItemInfo>* options )
|
||||
{
|
||||
if ( !options ) return;
|
||||
|
||||
RimProject* proj = RimProject::current();
|
||||
if ( proj )
|
||||
{
|
||||
const auto& coll = proj->activeOilField()->seismicCollection().p();
|
||||
|
||||
for ( auto* c : coll->seismicData() )
|
||||
{
|
||||
options->push_back( caf::PdmOptionItemInfo( QString::fromStdString( c->userDescription() ), c, false, c->uiIconProvider() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTools::seismicDataOptionItems( QList<caf::PdmOptionItemInfo>* options, cvf::BoundingBox worldBBox, bool basicDataOnly )
|
||||
{
|
||||
if ( !options ) return;
|
||||
|
||||
@ -388,7 +408,17 @@ void RimTools::seismicDataOptionItems( QList<caf::PdmOptionItemInfo>* options, c
|
||||
for ( auto* c : coll->seismicData() )
|
||||
{
|
||||
if ( c->boundingBox()->intersects( worldBBox ) )
|
||||
options->push_back( caf::PdmOptionItemInfo( c->userDescription(), c, false, c->uiIconProvider() ) );
|
||||
options->push_back( caf::PdmOptionItemInfo( QString::fromStdString( c->userDescription() ), c, false, c->uiIconProvider() ) );
|
||||
}
|
||||
|
||||
if ( !basicDataOnly )
|
||||
{
|
||||
for ( auto* c : coll->differenceData() )
|
||||
{
|
||||
if ( c->boundingBox()->intersects( worldBBox ) )
|
||||
options->push_back(
|
||||
caf::PdmOptionItemInfo( QString::fromStdString( c->userDescription() ), c, false, c->uiIconProvider() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,8 @@ public:
|
||||
static void eclipseCaseOptionItems( QList<caf::PdmOptionItemInfo>* options );
|
||||
static void geoMechCaseOptionItems( QList<caf::PdmOptionItemInfo>* options );
|
||||
static void colorLegendOptionItems( QList<caf::PdmOptionItemInfo>* options );
|
||||
static void seismicDataOptionItems( QList<caf::PdmOptionItemInfo>* options, cvf::BoundingBox worldBBox );
|
||||
static void seismicDataOptionItems( QList<caf::PdmOptionItemInfo>* options, cvf::BoundingBox worldBBox, bool basicDataOnly = false );
|
||||
static void seismicDataOptionItems( QList<caf::PdmOptionItemInfo>* options );
|
||||
|
||||
static RimWellPathCollection* wellPathCollection();
|
||||
static RimWellPath* firstWellPath();
|
||||
|
@ -1,6 +1,8 @@
|
||||
set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSeismicDataCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSeismicDataInterface.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSeismicData.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSeismicDifferenceData.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSeismicSectionCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSeismicSection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSeismicAlphaMapper.h
|
||||
@ -14,6 +16,8 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSeismicSection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSeismicAlphaMapper.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSEGYConvertOptions.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSeismicDataInterface.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSeismicDifferenceData.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
|
||||
|
@ -66,10 +66,6 @@ RimSeismicData::RimSeismicData()
|
||||
CAF_PDM_InitFieldNoDefault( &m_filename, "SeismicFilePath", "File" );
|
||||
m_filename.uiCapability()->setUiReadOnly( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_legendConfig, "LegendDefinition", "Color Legend" );
|
||||
m_legendConfig = new RimRegularLegendConfig();
|
||||
m_legendConfig.uiCapability()->setUiTreeHidden( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_metadata, "Metadata", "Metadata" );
|
||||
m_metadata.uiCapability()->setUiEditorTypeName( caf::PdmUiTableViewEditor::uiEditorTypeName() );
|
||||
m_metadata.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
||||
@ -78,15 +74,7 @@ RimSeismicData::RimSeismicData()
|
||||
m_metadata.uiCapability()->setUiReadOnly( true );
|
||||
m_metadata.xmlCapability()->disableIO();
|
||||
|
||||
CAF_PDM_InitField( &m_overrideDataRange, "overrideDataRange", false, "Override Data Range" );
|
||||
CAF_PDM_InitField( &m_userClipValue, "userClipValue", 0.0, "Clip Value" );
|
||||
|
||||
setDeletable( true );
|
||||
|
||||
m_boundingBox = std::make_shared<cvf::BoundingBox>();
|
||||
m_alphaValueMapper = std::make_shared<RimSeismicAlphaMapper>();
|
||||
|
||||
initColorLegend();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -189,9 +177,9 @@ QString RimSeismicData::fileName() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimSeismicData::userDescription()
|
||||
std::string RimSeismicData::userDescription() const
|
||||
{
|
||||
return m_userDescription;
|
||||
return m_userDescription().toStdString();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -238,9 +226,10 @@ void RimSeismicData::updateMetaData()
|
||||
auto [minDataValue, maxDataValue] = m_filereader->dataRange();
|
||||
double maxAbsDataValue = std::max( std::abs( minDataValue ), std::abs( maxDataValue ) );
|
||||
|
||||
if ( m_userClipValue <= 0.0 ) m_userClipValue = maxAbsDataValue;
|
||||
|
||||
m_userClipValue = std::clamp( m_userClipValue(), 0.0, maxAbsDataValue );
|
||||
auto [userClipEnabled, userClipValue] = m_userClipValue();
|
||||
if ( userClipValue <= 0.0 ) userClipValue = maxAbsDataValue;
|
||||
userClipValue = std::clamp( userClipValue, 0.0, maxAbsDataValue );
|
||||
m_userClipValue = std::make_pair( userClipEnabled, userClipValue );
|
||||
|
||||
m_filereader->histogramData( m_histogramXvalues, m_histogramYvalues );
|
||||
|
||||
@ -281,11 +270,8 @@ void RimSeismicData::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
|
||||
|
||||
auto cmGroup = uiOrdering.addNewGroup( "Color Mapping" );
|
||||
m_legendConfig->defineUiOrderingColorOnly( cmGroup );
|
||||
cmGroup->add( &m_overrideDataRange );
|
||||
if ( m_overrideDataRange() )
|
||||
{
|
||||
cmGroup->add( &m_userClipValue );
|
||||
}
|
||||
cmGroup->add( &m_userClipValue );
|
||||
cmGroup->add( &m_userMuteThreshold );
|
||||
|
||||
auto metaGroup = uiOrdering.addNewGroup( "File Information" );
|
||||
metaGroup->add( &m_metadata );
|
||||
@ -327,14 +313,6 @@ void RimSeismicData::defineEditorAttribute( const caf::PdmFieldHandle* field, QS
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::BoundingBox* RimSeismicData::boundingBox() const
|
||||
{
|
||||
return m_boundingBox.get();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -438,36 +416,12 @@ int RimSeismicData::toZIndex( double z ) const
|
||||
return zIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimSeismicData::histogramXvalues() const
|
||||
{
|
||||
return m_clippedHistogramXvalues;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimSeismicData::histogramYvalues() const
|
||||
{
|
||||
return m_clippedHistogramYvalues;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimSeismicData::alphaValues() const
|
||||
{
|
||||
return m_clippedAlphaValues;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSeismicData::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
|
||||
{
|
||||
if ( ( changedField == &m_overrideDataRange ) || ( changedField == &m_userClipValue ) )
|
||||
if ( ( changedField == &m_userMuteThreshold ) || ( changedField == &m_userClipValue ) )
|
||||
{
|
||||
updateDataRange( true );
|
||||
}
|
||||
@ -482,11 +436,11 @@ void RimSeismicData::updateDataRange( bool updatePlot )
|
||||
m_clippedHistogramYvalues.clear();
|
||||
m_clippedAlphaValues.clear();
|
||||
|
||||
double clipValue = m_userClipValue;
|
||||
auto [clipEnabled, clipValue] = m_userClipValue();
|
||||
|
||||
if ( m_overrideDataRange() )
|
||||
if ( clipEnabled )
|
||||
{
|
||||
m_activeDataRange = std::make_pair( -m_userClipValue, m_userClipValue );
|
||||
m_activeDataRange = std::make_pair( -clipValue, clipValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -513,7 +467,7 @@ void RimSeismicData::updateDataRange( bool updatePlot )
|
||||
m_alphaValueMapper->setDataRangeAndAlphas( m_activeDataRange.first, m_activeDataRange.second, m_clippedAlphaValues );
|
||||
m_legendConfig->setUserDefinedRange( m_activeDataRange.first, m_activeDataRange.second );
|
||||
|
||||
if ( updatePlot ) RiuMainWindow::instance()->seismicHistogramPanel()->showHistogram( this );
|
||||
if ( updatePlot ) RiuMainWindow::instance()->seismicHistogramPanel()->showHistogram( (RimSeismicDataInterface*)this );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -571,52 +525,19 @@ std::shared_ptr<ZGYAccess::SeismicSliceData>
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( ( sliceIndex < 0 ) || ( zMinIndex < 0 ) ) return nullptr;
|
||||
|
||||
auto data = m_filereader->slice( direction, sliceIndex, zMinIndex, zMaxIndex - zMinIndex );
|
||||
|
||||
double tmp = 0.0;
|
||||
float* pValue = data->values();
|
||||
const auto [minVal, maxVal] = dataRangeMinMax();
|
||||
const int nSize = data->size();
|
||||
data->limitTo( minVal, maxVal );
|
||||
|
||||
for ( int i = 0; i < nSize; i++, pValue++ )
|
||||
{
|
||||
tmp = *pValue;
|
||||
if ( tmp < minVal )
|
||||
*pValue = minVal;
|
||||
else if ( tmp > maxVal )
|
||||
*pValue = maxVal;
|
||||
}
|
||||
auto [doMute, muteThreshold] = m_userMuteThreshold();
|
||||
if ( doMute ) data->mute( muteThreshold );
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimRegularLegendConfig* RimSeismicData::legendConfig() const
|
||||
{
|
||||
return m_legendConfig();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSeismicAlphaMapper* RimSeismicData::alphaValueMapper() const
|
||||
{
|
||||
return m_alphaValueMapper.get();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSeismicData::initColorLegend()
|
||||
{
|
||||
m_legendConfig->setColorLegend( RimRegularLegendConfig::mapToColorLegend( RimRegularLegendConfig::ColorRangesType::BLUE_WHITE_RED ) );
|
||||
m_legendConfig->setMappingMode( RimRegularLegendConfig::MappingType::LINEAR_CONTINUOUS );
|
||||
m_legendConfig->setRangeMode( RimLegendConfig::RangeModeType::USER_DEFINED );
|
||||
m_legendConfig->setCenterLegendAroundZero( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -635,6 +556,8 @@ std::shared_ptr<ZGYAccess::SeismicSliceData>
|
||||
int zMinIndex = toZIndex( zMin );
|
||||
int zMaxIndex = toZIndex( zMax );
|
||||
|
||||
if ( ( startInlineIndex < 0 ) || ( startXlineIndex < 0 ) || ( zMinIndex < 0 ) ) return nullptr;
|
||||
|
||||
int diffI = std::abs( startInlineIndex - stopInlineIndex );
|
||||
int diffX = std::abs( startXlineIndex - stopXlineIndex );
|
||||
|
||||
@ -704,6 +627,12 @@ std::shared_ptr<ZGYAccess::SeismicSliceData>
|
||||
}
|
||||
}
|
||||
|
||||
const auto [minVal, maxVal] = dataRangeMinMax();
|
||||
retdata->limitTo( minVal, maxVal );
|
||||
|
||||
auto [doMute, muteThreshold] = m_userMuteThreshold();
|
||||
if ( doMute ) retdata->mute( muteThreshold );
|
||||
|
||||
return retdata;
|
||||
}
|
||||
|
||||
@ -720,9 +649,11 @@ float RimSeismicData::valueAt( cvf::Vec3d worldCoord )
|
||||
int xIndex = toXlineIndex( xline );
|
||||
int zIndex = toZIndex( std::abs( worldCoord[2] ) );
|
||||
|
||||
auto slice = m_filereader->trace( iIndex, xIndex, zIndex, 1 );
|
||||
|
||||
if ( slice->size() == 1 ) return slice->values()[0];
|
||||
if ( ( iIndex >= 0 ) && ( xIndex >= 0 ) && ( zIndex >= 0 ) )
|
||||
{
|
||||
auto slice = m_filereader->trace( iIndex, xIndex, zIndex, 1 );
|
||||
if ( slice->size() == 1 ) return slice->values()[0];
|
||||
}
|
||||
}
|
||||
|
||||
return std::nanf( "" );
|
||||
|
@ -17,37 +17,19 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RimSeismicDataInterface.h"
|
||||
|
||||
#include "RiaSeismicDefines.h"
|
||||
|
||||
#include "cafFilePath.h"
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
class RimGenericParameter;
|
||||
class RimSeismicAlphaMapper;
|
||||
class RimRegularLegendConfig;
|
||||
class RifSeismicReader;
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class BoundingBox;
|
||||
} // namespace cvf
|
||||
|
||||
namespace ZGYAccess
|
||||
{
|
||||
class SeismicSliceData;
|
||||
}
|
||||
|
||||
class RimSeismicData : public caf::PdmObject
|
||||
class RimSeismicData : public RimSeismicDataInterface
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
@ -58,51 +40,43 @@ public:
|
||||
void setFileName( QString filename );
|
||||
QString fileName() const;
|
||||
|
||||
QString userDescription();
|
||||
void setUserDescription( QString description );
|
||||
std::string userDescription() const override;
|
||||
void setUserDescription( QString description );
|
||||
|
||||
void updateMetaData();
|
||||
double zMin() const override;
|
||||
double zMax() const override;
|
||||
double zStep() const override;
|
||||
|
||||
double zMin() const;
|
||||
double zMax() const;
|
||||
double zStep() const;
|
||||
int inlineMin() const override;
|
||||
int inlineMax() const override;
|
||||
int inlineStep() const override;
|
||||
|
||||
int inlineMin() const;
|
||||
int inlineMax() const;
|
||||
int inlineStep() const;
|
||||
int xlineMin() const override;
|
||||
int xlineMax() const override;
|
||||
int xlineStep() const override;
|
||||
|
||||
int xlineMin() const;
|
||||
int xlineMax() const;
|
||||
int xlineStep() const;
|
||||
std::vector<cvf::Vec3d> worldOutline() const override;
|
||||
|
||||
std::vector<double> histogramXvalues() const;
|
||||
std::vector<double> histogramYvalues() const;
|
||||
std::vector<double> alphaValues() const;
|
||||
|
||||
std::vector<cvf::Vec3d> worldOutline() const;
|
||||
|
||||
cvf::Vec3d convertToWorldCoords( int iLine, int xLine, double depth );
|
||||
std::pair<int, int> convertToInlineXline( cvf::Vec3d worldCoords );
|
||||
cvf::Vec3d convertToWorldCoords( int iLine, int xLine, double depth ) override;
|
||||
std::pair<int, int> convertToInlineXline( cvf::Vec3d worldCoords ) override;
|
||||
|
||||
std::shared_ptr<ZGYAccess::SeismicSliceData>
|
||||
sliceData( RiaDefines::SeismicSliceDirection direction, int sliceNumber, double zMin, double zMax );
|
||||
sliceData( RiaDefines::SeismicSliceDirection direction, int sliceNumber, double zMin, double zMax ) override;
|
||||
std::shared_ptr<ZGYAccess::SeismicSliceData>
|
||||
sliceData( double worldX1, double worldY1, double worldX2, double worldY2, double zMin, double zMax );
|
||||
sliceData( double worldX1, double worldY1, double worldX2, double worldY2, double zMin, double zMax ) override;
|
||||
|
||||
float valueAt( cvf::Vec3d worldCoord );
|
||||
float valueAt( cvf::Vec3d worldCoord ) override;
|
||||
|
||||
std::pair<double, double> dataRangeMinMax() const;
|
||||
|
||||
RimRegularLegendConfig* legendConfig() const;
|
||||
RimSeismicAlphaMapper* alphaValueMapper() const;
|
||||
|
||||
cvf::BoundingBox* boundingBox() const;
|
||||
std::pair<double, double> dataRangeMinMax() const override;
|
||||
|
||||
protected:
|
||||
void initAfterRead() override;
|
||||
void updateMetaData();
|
||||
void initAfterRead() override;
|
||||
|
||||
caf::PdmFieldHandle* userDescriptionField() override;
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
|
||||
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
|
||||
void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
|
||||
@ -110,7 +84,6 @@ private:
|
||||
void updateDataRange( bool updatePlot );
|
||||
bool openFileIfNotOpen();
|
||||
void logError( QString msg );
|
||||
void initColorLegend();
|
||||
|
||||
int toInlineIndex( int inLine ) const;
|
||||
int toXlineIndex( int xLine ) const;
|
||||
@ -120,25 +93,13 @@ private:
|
||||
caf::PdmField<caf::FilePath> m_filename;
|
||||
caf::PdmField<QString> m_userDescription;
|
||||
caf::PdmChildArrayField<RimGenericParameter*> m_metadata;
|
||||
caf::PdmChildField<RimRegularLegendConfig*> m_legendConfig;
|
||||
|
||||
caf::PdmField<bool> m_overrideDataRange;
|
||||
caf::PdmField<double> m_userClipValue;
|
||||
|
||||
double m_zStep;
|
||||
cvf::Vec3i m_inlineInfo;
|
||||
cvf::Vec3i m_xlineInfo;
|
||||
std::shared_ptr<cvf::BoundingBox> m_boundingBox;
|
||||
std::vector<double> m_histogramXvalues;
|
||||
std::vector<double> m_histogramYvalues;
|
||||
std::vector<double> m_clippedHistogramXvalues;
|
||||
std::vector<double> m_clippedHistogramYvalues;
|
||||
std::vector<double> m_clippedAlphaValues;
|
||||
std::vector<cvf::Vec3d> m_worldOutline;
|
||||
std::pair<double, double> m_activeDataRange;
|
||||
std::pair<double, double> m_fileDataRange;
|
||||
|
||||
std::shared_ptr<RimSeismicAlphaMapper> m_alphaValueMapper;
|
||||
double m_zStep;
|
||||
cvf::Vec3i m_inlineInfo;
|
||||
cvf::Vec3i m_xlineInfo;
|
||||
std::vector<cvf::Vec3d> m_worldOutline;
|
||||
std::pair<double, double> m_activeDataRange;
|
||||
std::pair<double, double> m_fileDataRange;
|
||||
|
||||
std::shared_ptr<RifSeismicReader> m_filereader;
|
||||
int m_nErrorsLogged;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "RimGridView.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSeismicData.h"
|
||||
#include "RimSeismicDifferenceData.h"
|
||||
#include "RimSeismicSectionCollection.h"
|
||||
|
||||
#include <QFile>
|
||||
@ -41,6 +42,9 @@ RimSeismicDataCollection::RimSeismicDataCollection()
|
||||
CAF_PDM_InitFieldNoDefault( &m_seismicData, "SeismicData", "Seismic Data" );
|
||||
m_seismicData.uiCapability()->setUiTreeHidden( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_differenceData, "DifferenceData", "Seismic Difference Data" );
|
||||
m_differenceData.uiCapability()->setUiTreeHidden( true );
|
||||
|
||||
setDeletable( false );
|
||||
}
|
||||
|
||||
@ -54,7 +58,7 @@ RimSeismicDataCollection::~RimSeismicDataCollection()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSeismicData* RimSeismicDataCollection::importSeismicFromFile( const QString fileName )
|
||||
RimSeismicDataInterface* RimSeismicDataCollection::importSeismicFromFile( const QString fileName )
|
||||
{
|
||||
RimSeismicData* seisData = new RimSeismicData();
|
||||
seisData->setFileName( fileName );
|
||||
@ -77,6 +81,14 @@ std::vector<RimSeismicData*> RimSeismicDataCollection::seismicData() const
|
||||
return m_seismicData.childrenByType();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimSeismicDifferenceData*> RimSeismicDataCollection::differenceData() const
|
||||
{
|
||||
return m_differenceData.childrenByType();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -91,7 +103,7 @@ bool RimSeismicDataCollection::isEmpty()
|
||||
void RimSeismicDataCollection::onChildDeleted( caf::PdmChildArrayFieldHandle* childArray, std::vector<caf::PdmObjectHandle*>& referringObjects )
|
||||
{
|
||||
updateViews();
|
||||
if ( m_seismicData.size() == 0 ) updateTreeForAllViews();
|
||||
if ( ( m_seismicData.size() + m_differenceData.size() ) == 0 ) updateTreeForAllViews();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -125,3 +137,24 @@ void RimSeismicDataCollection::updateTreeForAllViews()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSeismicDataInterface* RimSeismicDataCollection::createDifferenceSeismicData( RimSeismicData* data1, RimSeismicData* data2 )
|
||||
{
|
||||
if ( ( data1 == nullptr ) || ( data2 == nullptr ) ) return nullptr;
|
||||
|
||||
if ( !data1->gridIsEqual( data2 ) ) return nullptr;
|
||||
|
||||
RimSeismicDifferenceData* retdata = new RimSeismicDifferenceData();
|
||||
retdata->setInputData( data1, data2 );
|
||||
retdata->setUserDescription( "Difference" );
|
||||
|
||||
m_differenceData.push_back( retdata );
|
||||
|
||||
updateAllRequiredEditors();
|
||||
if ( m_differenceData.size() == 1 ) updateTreeForAllViews();
|
||||
|
||||
return retdata;
|
||||
}
|
||||
|
@ -24,7 +24,9 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
class RimSeismicDataInterface;
|
||||
class RimSeismicData;
|
||||
class RimSeismicDifferenceData;
|
||||
|
||||
class RimSeismicDataCollection : public caf::PdmObject
|
||||
{
|
||||
@ -34,11 +36,13 @@ public:
|
||||
RimSeismicDataCollection();
|
||||
~RimSeismicDataCollection() override;
|
||||
|
||||
RimSeismicData* importSeismicFromFile( const QString file );
|
||||
RimSeismicDataInterface* importSeismicFromFile( const QString file );
|
||||
RimSeismicDataInterface* createDifferenceSeismicData( RimSeismicData* data1, RimSeismicData* data2 );
|
||||
|
||||
bool isEmpty();
|
||||
|
||||
std::vector<RimSeismicData*> seismicData() const;
|
||||
std::vector<RimSeismicData*> seismicData() const;
|
||||
std::vector<RimSeismicDifferenceData*> differenceData() const;
|
||||
|
||||
protected:
|
||||
void onChildDeleted( caf::PdmChildArrayFieldHandle* childArray, std::vector<caf::PdmObjectHandle*>& referringObjects ) override;
|
||||
@ -46,5 +50,6 @@ protected:
|
||||
void updateTreeForAllViews();
|
||||
|
||||
private:
|
||||
caf::PdmChildArrayField<RimSeismicData*> m_seismicData;
|
||||
caf::PdmChildArrayField<RimSeismicData*> m_seismicData;
|
||||
caf::PdmChildArrayField<RimSeismicDifferenceData*> m_differenceData;
|
||||
};
|
||||
|
@ -0,0 +1,139 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2023 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 "RimSeismicDataInterface.h"
|
||||
|
||||
#include "RimRegularLegendConfig.h"
|
||||
#include "RimSeismicAlphaMapper.h"
|
||||
|
||||
#include "cvfBoundingBox.h"
|
||||
|
||||
CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimSeismicDataInterface, "SeismicDataInterface" ); // Abstract class.
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSeismicDataInterface::RimSeismicDataInterface()
|
||||
{
|
||||
CAF_PDM_InitObject( "SeismicDataBase" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_legendConfig, "LegendDefinition", "Color Legend" );
|
||||
m_legendConfig = new RimRegularLegendConfig();
|
||||
m_legendConfig.uiCapability()->setUiTreeHidden( true );
|
||||
|
||||
CAF_PDM_InitField( &m_userClipValue, "userClipValue", std::make_pair( false, 0.0 ), "Clip Value" );
|
||||
CAF_PDM_InitField( &m_userMuteThreshold,
|
||||
"userMuteThreshold",
|
||||
std::make_pair( false, 0.0 ),
|
||||
"Mute Threshold",
|
||||
"",
|
||||
"Samples with an absolute value below the threshold will be replaced with 0." );
|
||||
|
||||
m_alphaValueMapper = std::make_shared<RimSeismicAlphaMapper>();
|
||||
m_boundingBox = std::make_shared<cvf::BoundingBox>();
|
||||
|
||||
initColorLegend();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSeismicDataInterface::~RimSeismicDataInterface()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimSeismicDataInterface::gridIsEqual( RimSeismicDataInterface* other )
|
||||
{
|
||||
if ( other == nullptr ) return false;
|
||||
|
||||
bool equal = ( inlineMin() == other->inlineMin() ) && ( inlineMax() == other->inlineMax() ) && ( inlineStep() == other->inlineStep() );
|
||||
equal = equal && ( xlineMin() == other->xlineMin() ) && ( xlineMax() == other->xlineMax() ) && ( xlineStep() == other->xlineStep() );
|
||||
equal = equal && ( zMin() == other->zMin() ) && ( zMax() == other->zMax() ) && ( zStep() == other->zStep() );
|
||||
|
||||
return equal;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimRegularLegendConfig* RimSeismicDataInterface::legendConfig() const
|
||||
{
|
||||
return m_legendConfig();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimSeismicDataInterface::hasValidData() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSeismicDataInterface::initColorLegend()
|
||||
{
|
||||
m_legendConfig->setColorLegend( RimRegularLegendConfig::mapToColorLegend( RimRegularLegendConfig::ColorRangesType::BLUE_WHITE_RED ) );
|
||||
m_legendConfig->setMappingMode( RimRegularLegendConfig::MappingType::LINEAR_CONTINUOUS );
|
||||
m_legendConfig->setRangeMode( RimLegendConfig::RangeModeType::USER_DEFINED );
|
||||
m_legendConfig->setCenterLegendAroundZero( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSeismicAlphaMapper* RimSeismicDataInterface::alphaValueMapper() const
|
||||
{
|
||||
return m_alphaValueMapper.get();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::BoundingBox* RimSeismicDataInterface::boundingBox() const
|
||||
{
|
||||
return m_boundingBox.get();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimSeismicDataInterface::histogramXvalues() const
|
||||
{
|
||||
return m_clippedHistogramXvalues;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimSeismicDataInterface::histogramYvalues() const
|
||||
{
|
||||
return m_clippedHistogramYvalues;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimSeismicDataInterface::alphaValues() const
|
||||
{
|
||||
return m_clippedAlphaValues;
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2023 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 "RiaSeismicDefines.h"
|
||||
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class RimSeismicAlphaMapper;
|
||||
class RimRegularLegendConfig;
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class BoundingBox;
|
||||
} // namespace cvf
|
||||
|
||||
namespace ZGYAccess
|
||||
{
|
||||
class SeismicSliceData;
|
||||
}
|
||||
|
||||
class RimSeismicDataInterface : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
protected:
|
||||
RimSeismicDataInterface();
|
||||
~RimSeismicDataInterface() override;
|
||||
|
||||
// common functionality
|
||||
public:
|
||||
virtual bool gridIsEqual( RimSeismicDataInterface* other );
|
||||
virtual RimRegularLegendConfig* legendConfig() const;
|
||||
virtual RimSeismicAlphaMapper* alphaValueMapper() const;
|
||||
|
||||
// interface to be implemented by subclasses
|
||||
public:
|
||||
virtual double zMin() const = 0;
|
||||
virtual double zMax() const = 0;
|
||||
virtual double zStep() const = 0;
|
||||
|
||||
virtual int inlineMin() const = 0;
|
||||
virtual int inlineMax() const = 0;
|
||||
virtual int inlineStep() const = 0;
|
||||
|
||||
virtual int xlineMin() const = 0;
|
||||
virtual int xlineMax() const = 0;
|
||||
virtual int xlineStep() const = 0;
|
||||
|
||||
virtual std::vector<cvf::Vec3d> worldOutline() const = 0;
|
||||
|
||||
virtual cvf::Vec3d convertToWorldCoords( int iLine, int xLine, double depth ) = 0;
|
||||
virtual std::pair<int, int> convertToInlineXline( cvf::Vec3d worldCoords ) = 0;
|
||||
|
||||
virtual std::shared_ptr<ZGYAccess::SeismicSliceData>
|
||||
sliceData( RiaDefines::SeismicSliceDirection direction, int sliceNumber, double zMin, double zMax ) = 0;
|
||||
virtual std::shared_ptr<ZGYAccess::SeismicSliceData>
|
||||
sliceData( double worldX1, double worldY1, double worldX2, double worldY2, double zMin, double zMax ) = 0;
|
||||
|
||||
virtual float valueAt( cvf::Vec3d worldCoord ) = 0;
|
||||
|
||||
virtual std::pair<double, double> dataRangeMinMax() const = 0;
|
||||
|
||||
virtual std::string userDescription() const = 0;
|
||||
|
||||
// optional subclass overrides
|
||||
virtual bool hasValidData() const;
|
||||
virtual cvf::BoundingBox* boundingBox() const;
|
||||
virtual std::vector<double> histogramXvalues() const;
|
||||
virtual std::vector<double> histogramYvalues() const;
|
||||
virtual std::vector<double> alphaValues() const;
|
||||
|
||||
protected:
|
||||
void initColorLegend();
|
||||
|
||||
protected:
|
||||
caf::PdmChildField<RimRegularLegendConfig*> m_legendConfig;
|
||||
std::shared_ptr<RimSeismicAlphaMapper> m_alphaValueMapper;
|
||||
std::shared_ptr<cvf::BoundingBox> m_boundingBox;
|
||||
|
||||
std::vector<double> m_histogramXvalues;
|
||||
std::vector<double> m_histogramYvalues;
|
||||
std::vector<double> m_clippedHistogramXvalues;
|
||||
std::vector<double> m_clippedHistogramYvalues;
|
||||
std::vector<double> m_clippedAlphaValues;
|
||||
|
||||
caf::PdmField<std::pair<bool, double>> m_userClipValue;
|
||||
caf::PdmField<std::pair<bool, double>> m_userMuteThreshold;
|
||||
};
|
@ -0,0 +1,586 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2022 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 "RimSeismicDifferenceData.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RifOpenVDSReader.h"
|
||||
#include "RifSeismicZGYReader.h"
|
||||
|
||||
#include "Rim3dView.h"
|
||||
#include "RimOilField.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimRegularLegendConfig.h"
|
||||
#include "RimSeismicAlphaMapper.h"
|
||||
#include "RimSeismicData.h"
|
||||
#include "RimSeismicDataCollection.h"
|
||||
#include "RimStringParameter.h"
|
||||
#include "RimTools.h"
|
||||
|
||||
#include "RiuMainWindow.h"
|
||||
#include "RiuSeismicHistogramPanel.h"
|
||||
|
||||
#include <zgyaccess/seismicslice.h>
|
||||
#include <zgyaccess/zgy_histogram.h>
|
||||
|
||||
#include "cafPdmUiLineEditor.h"
|
||||
#include "cafPdmUiTableViewEditor.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
#include "cvfBoundingBox.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QValidator>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <tuple>
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimSeismicDifferenceData, "SeismicDifferenceData" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSeismicDifferenceData::RimSeismicDifferenceData()
|
||||
: m_fileDataRange( 0, 0 )
|
||||
, m_activeDataRange( 0, 0 )
|
||||
, m_inputDataOK( false )
|
||||
{
|
||||
CAF_PDM_InitObject( "SeismicDifferenceData", ":/SeismicDelta16x16.png" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_userDescription, "SeismicUserDecription", "Name" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_nameProxy, "NameProxy", "Name Proxy" );
|
||||
m_nameProxy.registerGetMethod( this, &RimSeismicDifferenceData::fullName );
|
||||
m_nameProxy.uiCapability()->setUiReadOnly( true );
|
||||
m_nameProxy.uiCapability()->setUiHidden( true );
|
||||
m_nameProxy.xmlCapability()->disableIO();
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_seismicData1, "SeismicData1", "Seismic Data 1" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_seismicData2, "SeismicData2", "Seismic Data 2" );
|
||||
|
||||
setDeletable( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSeismicDifferenceData::~RimSeismicDifferenceData()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSeismicDifferenceData::setInputData( RimSeismicDataInterface* data1, RimSeismicDataInterface* data2 )
|
||||
{
|
||||
m_seismicData1 = data1;
|
||||
m_seismicData2 = data2;
|
||||
|
||||
updateMetaData();
|
||||
updateDataRange( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSeismicDifferenceData::initAfterRead()
|
||||
{
|
||||
updateMetaData();
|
||||
updateDataRange( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimSeismicDifferenceData::isInputDataOK() const
|
||||
{
|
||||
return m_inputDataOK && ( m_seismicData1 != nullptr ) && ( m_seismicData2 != nullptr );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::string RimSeismicDifferenceData::userDescription() const
|
||||
{
|
||||
return fullName().toStdString();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSeismicDifferenceData::setUserDescription( QString description )
|
||||
{
|
||||
m_userDescription = description;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmFieldHandle* RimSeismicDifferenceData::userDescriptionField()
|
||||
{
|
||||
return &m_nameProxy;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimSeismicDifferenceData::fullName() const
|
||||
{
|
||||
QString name = m_userDescription();
|
||||
|
||||
if ( name.isEmpty() ) name = "Difference";
|
||||
|
||||
if ( isInputDataOK() )
|
||||
{
|
||||
name += QString( " [%1 - %2]" )
|
||||
.arg( QString::fromStdString( m_seismicData1->userDescription() ) )
|
||||
.arg( QString::fromStdString( m_seismicData2->userDescription() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
name += " [Input data not valid]";
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimSeismicDifferenceData::hasValidData() const
|
||||
{
|
||||
return m_inputDataOK && ( m_seismicData1 != nullptr ) && ( m_seismicData2 != nullptr );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<cvf::Vec3d> RimSeismicDifferenceData::worldOutline() const
|
||||
{
|
||||
if ( !isInputDataOK() ) return {};
|
||||
return m_seismicData1->worldOutline();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSeismicDifferenceData::updateMetaData()
|
||||
{
|
||||
m_inputDataOK = false;
|
||||
if ( ( m_seismicData1 == nullptr ) || ( m_seismicData2 == nullptr ) ) return;
|
||||
|
||||
m_inputDataOK = m_seismicData1->gridIsEqual( m_seismicData2 );
|
||||
|
||||
if ( !m_inputDataOK ) return;
|
||||
|
||||
m_boundingBox->reset();
|
||||
m_boundingBox->add( *m_seismicData1->boundingBox() );
|
||||
|
||||
auto [min1, max1] = m_seismicData1->dataRangeMinMax();
|
||||
auto [min2, max2] = m_seismicData2->dataRangeMinMax();
|
||||
|
||||
m_fileDataRange = std::make_pair( std::min( min1, min2 ), std::max( max1, max2 ) );
|
||||
|
||||
generateHistogram();
|
||||
|
||||
auto [minDataValue, maxDataValue] = m_fileDataRange;
|
||||
double maxAbsDataValue = std::max( std::abs( minDataValue ), std::abs( maxDataValue ) );
|
||||
|
||||
auto [userClipEnabled, userClipValue] = m_userClipValue();
|
||||
if ( userClipValue <= 0.0 ) userClipValue = maxAbsDataValue;
|
||||
userClipValue = std::clamp( userClipValue, 0.0, maxAbsDataValue );
|
||||
m_userClipValue = std::make_pair( userClipEnabled, userClipValue );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSeismicDifferenceData::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
auto genGroup = uiOrdering.addNewGroup( "General" );
|
||||
genGroup->add( &m_userDescription );
|
||||
|
||||
auto diffGroup = uiOrdering.addNewGroup( "Input Data" );
|
||||
diffGroup->add( &m_seismicData1 );
|
||||
diffGroup->add( &m_seismicData2 );
|
||||
|
||||
auto cmGroup = uiOrdering.addNewGroup( "Color Mapping" );
|
||||
m_legendConfig->defineUiOrderingColorOnly( cmGroup );
|
||||
cmGroup->add( &m_userClipValue );
|
||||
cmGroup->add( &m_userMuteThreshold );
|
||||
|
||||
uiOrdering.skipRemainingFields();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSeismicDifferenceData::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= "" */ )
|
||||
{
|
||||
uiTreeOrdering.skipRemainingChildren();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSeismicDifferenceData::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
|
||||
{
|
||||
if ( field == &m_userClipValue )
|
||||
{
|
||||
auto myAttr = dynamic_cast<caf::PdmUiLineEditorAttribute*>( attribute );
|
||||
if ( myAttr )
|
||||
{
|
||||
myAttr->validator = new QDoubleValidator( 0.00001, std::numeric_limits<double>::infinity(), 6 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSeismicDifferenceData::zMin() const
|
||||
{
|
||||
if ( !isInputDataOK() ) return 0.0;
|
||||
return std::abs( m_boundingBox->max().z() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSeismicDifferenceData::zMax() const
|
||||
{
|
||||
if ( !isInputDataOK() ) return 0.0;
|
||||
return std::abs( m_boundingBox->min().z() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSeismicDifferenceData::zStep() const
|
||||
{
|
||||
if ( !isInputDataOK() ) return 1.0;
|
||||
return m_seismicData1->zStep();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimSeismicDifferenceData::inlineMin() const
|
||||
{
|
||||
if ( !isInputDataOK() ) return 0;
|
||||
return m_seismicData1->inlineMin();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimSeismicDifferenceData::inlineMax() const
|
||||
{
|
||||
if ( !isInputDataOK() ) return 0;
|
||||
return m_seismicData1->inlineMax();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimSeismicDifferenceData::inlineStep() const
|
||||
{
|
||||
if ( !isInputDataOK() ) return 1;
|
||||
return m_seismicData1->inlineStep();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimSeismicDifferenceData::xlineMin() const
|
||||
{
|
||||
if ( !isInputDataOK() ) return 0;
|
||||
return m_seismicData1->xlineMin();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimSeismicDifferenceData::xlineMax() const
|
||||
{
|
||||
if ( !isInputDataOK() ) return 0;
|
||||
return m_seismicData1->xlineMax();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimSeismicDifferenceData::xlineStep() const
|
||||
{
|
||||
if ( !isInputDataOK() ) return 1;
|
||||
return m_seismicData1->xlineStep();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSeismicDifferenceData::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
|
||||
{
|
||||
if ( ( changedField == &m_userMuteThreshold ) || ( changedField == &m_userClipValue ) )
|
||||
{
|
||||
updateDataRange( true );
|
||||
}
|
||||
else if ( ( changedField == &m_seismicData1 ) || ( changedField == &m_seismicData2 ) )
|
||||
{
|
||||
updateMetaData();
|
||||
updateDataRange( true );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSeismicDifferenceData::updateDataRange( bool updatePlot )
|
||||
{
|
||||
m_clippedHistogramXvalues.clear();
|
||||
m_clippedHistogramYvalues.clear();
|
||||
m_clippedAlphaValues.clear();
|
||||
|
||||
if ( !isInputDataOK() )
|
||||
{
|
||||
if ( updatePlot ) RiuMainWindow::instance()->seismicHistogramPanel()->showHistogram( (RimSeismicDataInterface*)nullptr );
|
||||
return;
|
||||
}
|
||||
|
||||
auto [clipEnabled, clipValue] = m_userClipValue();
|
||||
|
||||
if ( clipEnabled )
|
||||
{
|
||||
m_activeDataRange = std::make_pair( -clipValue, clipValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_activeDataRange = std::make_pair( m_fileDataRange.first, m_fileDataRange.second );
|
||||
clipValue = m_fileDataRange.second;
|
||||
}
|
||||
|
||||
const int nVals = (int)m_histogramXvalues.size();
|
||||
|
||||
for ( int i = 0; i < nVals; i++ )
|
||||
{
|
||||
double tmp = std::abs( m_histogramXvalues[i] );
|
||||
if ( tmp > clipValue ) continue;
|
||||
m_clippedHistogramXvalues.push_back( m_histogramXvalues[i] );
|
||||
m_clippedHistogramYvalues.push_back( m_histogramYvalues[i] );
|
||||
}
|
||||
|
||||
double maxRawValue = *std::max_element( m_clippedHistogramYvalues.begin(), m_clippedHistogramYvalues.end() );
|
||||
for ( auto val : m_clippedHistogramYvalues )
|
||||
{
|
||||
m_clippedAlphaValues.push_back( 1.0 - std::clamp( val / maxRawValue, 0.0, 1.0 ) );
|
||||
}
|
||||
|
||||
m_alphaValueMapper->setDataRangeAndAlphas( m_activeDataRange.first, m_activeDataRange.second, m_clippedAlphaValues );
|
||||
m_legendConfig->setUserDefinedRange( m_activeDataRange.first, m_activeDataRange.second );
|
||||
|
||||
if ( updatePlot ) RiuMainWindow::instance()->seismicHistogramPanel()->showHistogram( (RimSeismicDataInterface*)this );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RimSeismicDifferenceData::convertToWorldCoords( int iLine, int xLine, double depth )
|
||||
{
|
||||
if ( !isInputDataOK() ) return { 0, 0, 0 };
|
||||
|
||||
return m_seismicData1->convertToWorldCoords( iLine, xLine, depth );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<int, int> RimSeismicDifferenceData::convertToInlineXline( cvf::Vec3d worldCoords )
|
||||
{
|
||||
if ( !isInputDataOK() ) return { 0, 0 };
|
||||
|
||||
return m_seismicData1->convertToInlineXline( worldCoords );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<double, double> RimSeismicDifferenceData::dataRangeMinMax() const
|
||||
{
|
||||
if ( !isInputDataOK() ) return { 0, 0 };
|
||||
return m_activeDataRange;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::shared_ptr<ZGYAccess::SeismicSliceData>
|
||||
RimSeismicDifferenceData::sliceData( RiaDefines::SeismicSliceDirection direction, int sliceNumber, double zMin, double zMax )
|
||||
{
|
||||
if ( !isInputDataOK() ) return nullptr;
|
||||
|
||||
auto data1 = m_seismicData1->sliceData( direction, sliceNumber, zMin, zMax );
|
||||
auto data2 = m_seismicData2->sliceData( direction, sliceNumber, zMin, zMax );
|
||||
|
||||
if ( ( data1 == nullptr ) || ( data2 == nullptr ) ) return nullptr;
|
||||
|
||||
auto retdata = difference( data1.get(), data2.get() );
|
||||
|
||||
const auto [minVal, maxVal] = dataRangeMinMax();
|
||||
retdata->limitTo( minVal, maxVal );
|
||||
|
||||
auto [doMute, muteThreshold] = m_userMuteThreshold();
|
||||
if ( doMute ) retdata->mute( muteThreshold );
|
||||
|
||||
return retdata;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::shared_ptr<ZGYAccess::SeismicSliceData>
|
||||
RimSeismicDifferenceData::sliceData( double worldX1, double worldY1, double worldX2, double worldY2, double zMin, double zMax )
|
||||
{
|
||||
if ( !isInputDataOK() ) return nullptr;
|
||||
|
||||
auto data1 = m_seismicData1->sliceData( worldX1, worldY1, worldX2, worldY2, zMin, zMax );
|
||||
auto data2 = m_seismicData1->sliceData( worldX1, worldY1, worldX2, worldY2, zMin, zMax );
|
||||
|
||||
if ( ( data1 == nullptr ) || ( data2 == nullptr ) ) return nullptr;
|
||||
|
||||
auto retdata = difference( data1.get(), data2.get() );
|
||||
|
||||
const auto [minVal, maxVal] = dataRangeMinMax();
|
||||
retdata->limitTo( minVal, maxVal );
|
||||
|
||||
auto [doMute, muteThreshold] = m_userMuteThreshold();
|
||||
if ( doMute ) retdata->mute( muteThreshold );
|
||||
|
||||
return retdata;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float RimSeismicDifferenceData::valueAt( cvf::Vec3d worldCoord )
|
||||
{
|
||||
if ( !isInputDataOK() ) return std::nanf( "" );
|
||||
|
||||
float val1 = m_seismicData1->valueAt( worldCoord );
|
||||
float val2 = m_seismicData2->valueAt( worldCoord );
|
||||
|
||||
return val1 - val2;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo> RimSeismicDifferenceData::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
|
||||
if ( fieldNeedingOptions == &m_seismicData1 )
|
||||
{
|
||||
RimTools::seismicDataOptionItems( &options );
|
||||
}
|
||||
else if ( fieldNeedingOptions == &m_seismicData2 )
|
||||
{
|
||||
RimProject* proj = RimProject::current();
|
||||
if ( ( proj != nullptr ) && ( m_seismicData1() != nullptr ) )
|
||||
{
|
||||
const auto& coll = proj->activeOilField()->seismicCollection().p();
|
||||
|
||||
for ( auto seisData : coll->seismicData() )
|
||||
{
|
||||
if ( m_seismicData1()->gridIsEqual( seisData ) )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( QString::fromStdString( seisData->userDescription() ),
|
||||
seisData,
|
||||
false,
|
||||
seisData->uiIconProvider() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::shared_ptr<ZGYAccess::SeismicSliceData> RimSeismicDifferenceData::difference( ZGYAccess::SeismicSliceData* data1,
|
||||
ZGYAccess::SeismicSliceData* data2 )
|
||||
{
|
||||
std::shared_ptr<ZGYAccess::SeismicSliceData> retData = std::make_shared<ZGYAccess::SeismicSliceData>( data1->width(), data1->depth() );
|
||||
|
||||
float* pInput1 = data1->values();
|
||||
float* pInput2 = data2->values();
|
||||
float* pOutput = retData->values();
|
||||
|
||||
const int nValues = retData->size();
|
||||
|
||||
for ( int i = 0; i < nValues; i++, pInput1++, pInput2++, pOutput++ )
|
||||
{
|
||||
*pOutput = *pInput1 - *pInput2;
|
||||
}
|
||||
|
||||
return retData;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSeismicDifferenceData::generateHistogram()
|
||||
{
|
||||
auto [minVal, maxVal] = m_fileDataRange;
|
||||
|
||||
auto generator = std::make_unique<ZGYAccess::HistogramGenerator>( 200, minVal, maxVal );
|
||||
|
||||
const int iLineMin = m_seismicData1->inlineMin();
|
||||
const int iLineMax = m_seismicData1->inlineMax();
|
||||
const int iLineStep = m_seismicData1->inlineStep();
|
||||
|
||||
const double zMin = m_seismicData1->zMin();
|
||||
const double zMax = m_seismicData1->zMax();
|
||||
|
||||
for ( int iline = iLineMin; iline <= iLineMax; iline += iLineStep )
|
||||
{
|
||||
auto slicedata = sliceData( RiaDefines::SeismicSliceDirection::INLINE, iline, zMin, zMax );
|
||||
|
||||
if ( slicedata->size() > 0 )
|
||||
{
|
||||
std::vector<float> vec( slicedata->values(), slicedata->values() + slicedata->size() );
|
||||
|
||||
generator->addData( vec );
|
||||
|
||||
minVal = std::min( minVal, (double)*std::min_element( vec.begin(), vec.end() ) );
|
||||
maxVal = std::max( maxVal, (double)*std::max_element( vec.begin(), vec.end() ) );
|
||||
}
|
||||
}
|
||||
|
||||
auto hist = generator->getHistogram();
|
||||
|
||||
m_histogramXvalues = hist->Xvalues;
|
||||
m_histogramYvalues = hist->Yvalues;
|
||||
|
||||
m_fileDataRange = std::make_pair( minVal, maxVal );
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2023 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 "RimSeismicDataInterface.h"
|
||||
|
||||
#include "RiaSeismicDefines.h"
|
||||
|
||||
#include "cafFilePath.h"
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmProxyValueField.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
class RimGenericParameter;
|
||||
|
||||
class RimSeismicDifferenceData : public RimSeismicDataInterface
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimSeismicDifferenceData();
|
||||
~RimSeismicDifferenceData() override;
|
||||
|
||||
void setInputData( RimSeismicDataInterface* data1, RimSeismicDataInterface* data2 );
|
||||
|
||||
std::string userDescription() const override;
|
||||
void setUserDescription( QString description );
|
||||
|
||||
double zMin() const override;
|
||||
double zMax() const override;
|
||||
double zStep() const override;
|
||||
|
||||
int inlineMin() const override;
|
||||
int inlineMax() const override;
|
||||
int inlineStep() const override;
|
||||
|
||||
int xlineMin() const override;
|
||||
int xlineMax() const override;
|
||||
int xlineStep() const override;
|
||||
|
||||
std::vector<cvf::Vec3d> worldOutline() const override;
|
||||
|
||||
cvf::Vec3d convertToWorldCoords( int iLine, int xLine, double depth ) override;
|
||||
std::pair<int, int> convertToInlineXline( cvf::Vec3d worldCoords ) override;
|
||||
|
||||
std::shared_ptr<ZGYAccess::SeismicSliceData>
|
||||
sliceData( RiaDefines::SeismicSliceDirection direction, int sliceNumber, double zMin, double zMax ) override;
|
||||
std::shared_ptr<ZGYAccess::SeismicSliceData>
|
||||
sliceData( double worldX1, double worldY1, double worldX2, double worldY2, double zMin, double zMax ) override;
|
||||
|
||||
float valueAt( cvf::Vec3d worldCoord ) override;
|
||||
|
||||
std::pair<double, double> dataRangeMinMax() const override;
|
||||
|
||||
QString fullName() const;
|
||||
|
||||
bool hasValidData() const override;
|
||||
|
||||
protected:
|
||||
void initAfterRead() override;
|
||||
caf::PdmFieldHandle* userDescriptionField() override;
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
|
||||
|
||||
void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
|
||||
std::shared_ptr<ZGYAccess::SeismicSliceData> difference( ZGYAccess::SeismicSliceData* data1, ZGYAccess::SeismicSliceData* data2 );
|
||||
|
||||
private:
|
||||
void updateDataRange( bool updatePlot );
|
||||
void updateMetaData();
|
||||
bool isInputDataOK() const;
|
||||
void generateHistogram();
|
||||
|
||||
caf::PdmField<QString> m_userDescription;
|
||||
caf::PdmProxyValueField<QString> m_nameProxy;
|
||||
|
||||
caf::PdmPtrField<RimSeismicDataInterface*> m_seismicData1;
|
||||
caf::PdmPtrField<RimSeismicDataInterface*> m_seismicData2;
|
||||
|
||||
std::pair<double, double> m_activeDataRange;
|
||||
std::pair<double, double> m_fileDataRange;
|
||||
|
||||
bool m_inputDataOK;
|
||||
};
|
@ -24,7 +24,7 @@
|
||||
#include "Rim3dView.h"
|
||||
#include "RimRegularLegendConfig.h"
|
||||
#include "RimSeismicAlphaMapper.h"
|
||||
#include "RimSeismicData.h"
|
||||
#include "RimSeismicDataInterface.h"
|
||||
#include "RimTools.h"
|
||||
#include "RimWellPath.h"
|
||||
|
||||
@ -165,7 +165,7 @@ void RimSeismicSection::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderi
|
||||
genGrp->add( &m_userDescription );
|
||||
genGrp->add( &m_seismicData );
|
||||
|
||||
if ( m_seismicData() != nullptr )
|
||||
if ( m_seismicData != nullptr )
|
||||
{
|
||||
genGrp->add( &m_type );
|
||||
|
||||
@ -295,27 +295,27 @@ void RimSeismicSection::defineEditorAttribute( const caf::PdmFieldHandle* field,
|
||||
}
|
||||
else if ( ( field == &m_depthIndex ) || ( field == &m_inlineIndex ) || ( field == &m_xlineIndex ) )
|
||||
{
|
||||
if ( ( m_seismicData() != nullptr ) && m_seismicData->boundingBox()->isValid() )
|
||||
if ( ( m_seismicData != nullptr ) && m_seismicData->boundingBox()->isValid() )
|
||||
{
|
||||
auto* sliderAttrib = dynamic_cast<caf::PdmUiSliderEditorAttribute*>( attribute );
|
||||
if ( sliderAttrib != nullptr )
|
||||
{
|
||||
sliderAttrib->m_showSpinBox = true;
|
||||
int minVal = m_seismicData()->inlineMin();
|
||||
int maxVal = m_seismicData()->inlineMax();
|
||||
int stepVal = m_seismicData()->inlineStep();
|
||||
int minVal = m_seismicData->inlineMin();
|
||||
int maxVal = m_seismicData->inlineMax();
|
||||
int stepVal = m_seismicData->inlineStep();
|
||||
|
||||
if ( field == &m_xlineIndex )
|
||||
{
|
||||
minVal = m_seismicData()->xlineMin();
|
||||
maxVal = m_seismicData()->xlineMax();
|
||||
stepVal = m_seismicData()->xlineStep();
|
||||
minVal = m_seismicData->xlineMin();
|
||||
maxVal = m_seismicData->xlineMax();
|
||||
stepVal = m_seismicData->xlineStep();
|
||||
}
|
||||
else if ( field == &m_depthIndex )
|
||||
{
|
||||
minVal = m_seismicData()->zMin();
|
||||
maxVal = m_seismicData()->zMax();
|
||||
stepVal = m_seismicData()->zStep();
|
||||
minVal = m_seismicData->zMin();
|
||||
maxVal = m_seismicData->zMax();
|
||||
stepVal = m_seismicData->zStep();
|
||||
}
|
||||
sliderAttrib->m_maximum = maxVal;
|
||||
sliderAttrib->m_minimum = minVal;
|
||||
@ -326,9 +326,9 @@ void RimSeismicSection::defineEditorAttribute( const caf::PdmFieldHandle* field,
|
||||
else if ( ( field == &m_zUpperThreshold ) || ( field == &m_zLowerThreshold ) )
|
||||
{
|
||||
auto* sliderAttrib = dynamic_cast<caf::PdmUiSliderEditorAttribute*>( attribute );
|
||||
if ( ( sliderAttrib ) && ( m_seismicData() != nullptr ) )
|
||||
if ( ( sliderAttrib ) && ( m_seismicData != nullptr ) )
|
||||
{
|
||||
auto bb = m_seismicData()->boundingBox();
|
||||
auto bb = m_seismicData->boundingBox();
|
||||
if ( bb->isValid() )
|
||||
{
|
||||
sliderAttrib->m_minimum = -1 * bb->max().z();
|
||||
@ -476,9 +476,9 @@ cvf::ref<RigPolyLinesData> RimSeismicSection::polyLinesData() const
|
||||
pld->setPolyLine( line );
|
||||
}
|
||||
|
||||
if ( m_showSeismicOutline() && m_seismicData() != nullptr )
|
||||
if ( m_showSeismicOutline() && m_seismicData != nullptr )
|
||||
{
|
||||
auto outline = m_seismicData()->worldOutline();
|
||||
auto outline = m_seismicData->worldOutline();
|
||||
if ( outline.size() == 8 )
|
||||
{
|
||||
// seismic bounding box could be all the way up to the sea surface,
|
||||
@ -600,8 +600,16 @@ cvf::ref<RigTexturedSection> RimSeismicSection::texturedSection()
|
||||
{
|
||||
if ( m_texturedSection.isNull() ) m_texturedSection = new RigTexturedSection();
|
||||
|
||||
if ( m_texturedSection->isValid() || ( m_seismicData == nullptr ) || ( !m_seismicData->boundingBox()->isValid() ) )
|
||||
if ( ( m_seismicData == nullptr ) || ( !m_seismicData->hasValidData() ) || ( !m_seismicData->boundingBox()->isValid() ) )
|
||||
{
|
||||
m_texturedSection->setWhatToUpdate( RigTexturedSection::WhatToUpdateEnum::UPDATE_ALL );
|
||||
return m_texturedSection;
|
||||
}
|
||||
|
||||
if ( m_texturedSection->isValid() )
|
||||
{
|
||||
return m_texturedSection;
|
||||
}
|
||||
|
||||
std::vector<cvf::Vec3dArray> rects;
|
||||
std::vector<int> widths;
|
||||
@ -762,17 +770,17 @@ void RimSeismicSection::fieldChangedByUi( const caf::PdmFieldHandle* changedFiel
|
||||
|
||||
if ( changedField == &m_seismicData )
|
||||
{
|
||||
RiuMainWindow::instance()->seismicHistogramPanel()->showHistogram( m_seismicData() );
|
||||
RiuMainWindow::instance()->seismicHistogramPanel()->showHistogram( m_seismicData );
|
||||
initSliceRanges();
|
||||
|
||||
PdmObjectHandle* prevValue = oldValue.value<caf::PdmPointer<PdmObjectHandle>>().rawPtr();
|
||||
auto prevSeisData = dynamic_cast<RimSeismicData*>( prevValue );
|
||||
auto prevSeisData = dynamic_cast<RimSeismicDataInterface*>( prevValue );
|
||||
if ( prevSeisData != nullptr )
|
||||
{
|
||||
prevSeisData->legendConfig()->changed.disconnect( this );
|
||||
}
|
||||
|
||||
m_seismicData->legendConfig()->changed.connect( this, &RimSeismicSection::onLegendConfigChanged );
|
||||
if ( m_seismicData != nullptr )
|
||||
m_seismicData->legendConfig()->changed.connect( this, &RimSeismicSection::onLegendConfigChanged );
|
||||
|
||||
updateType = RigTexturedSection::WhatToUpdateEnum::UPDATE_ALL;
|
||||
}
|
||||
@ -801,15 +809,15 @@ void RimSeismicSection::fieldChangedByUi( const caf::PdmFieldHandle* changedFiel
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSeismicData* RimSeismicSection::seismicData() const
|
||||
RimSeismicDataInterface* RimSeismicSection::seismicData() const
|
||||
{
|
||||
return m_seismicData();
|
||||
return m_seismicData;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSeismicSection::setSeismicData( RimSeismicData* seisData )
|
||||
void RimSeismicSection::setSeismicData( RimSeismicDataInterface* seisData )
|
||||
{
|
||||
if ( m_seismicData != nullptr ) m_seismicData->legendConfig()->changed.disconnect( this );
|
||||
|
||||
@ -849,7 +857,7 @@ bool RimSeismicSection::isTransparent() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSeismicSection::initSliceRanges()
|
||||
{
|
||||
if ( ( m_seismicData() == nullptr ) || ( !m_seismicData->boundingBox()->isValid() ) ) return;
|
||||
if ( ( m_seismicData == nullptr ) || ( !m_seismicData->boundingBox()->isValid() ) ) return;
|
||||
|
||||
if ( m_zLowerThreshold < 0 ) m_zLowerThreshold = m_seismicData->zMax();
|
||||
if ( m_zUpperThreshold < 0 ) m_zUpperThreshold = m_seismicData->zMin();
|
||||
|
@ -48,7 +48,7 @@ class RigWellPath;
|
||||
class RigTexturedSection;
|
||||
class RivSeismicSectionPartMgr;
|
||||
class Rim3dView;
|
||||
class RimSeismicData;
|
||||
class RimSeismicDataInterface;
|
||||
class RimRegularLegendConfig;
|
||||
class RimSeismicAlphaMapper;
|
||||
class RimWellPath;
|
||||
@ -86,8 +86,8 @@ public:
|
||||
|
||||
RivSeismicSectionPartMgr* partMgr();
|
||||
|
||||
RimSeismicData* seismicData() const;
|
||||
void setSeismicData( RimSeismicData* seisData );
|
||||
RimSeismicDataInterface* seismicData() const;
|
||||
void setSeismicData( RimSeismicDataInterface* seisData );
|
||||
|
||||
RimRegularLegendConfig* legendConfig() const;
|
||||
RimSeismicAlphaMapper* alphaValueMapper() const;
|
||||
@ -130,14 +130,15 @@ private:
|
||||
void updateTextureSectionFromPoints( std::vector<cvf::Vec3d> points, double zmin, double zmax );
|
||||
std::vector<cvf::Vec3d> wellPathToSectionPoints( RigWellPath* wellpath, double zmin );
|
||||
|
||||
caf::PdmField<QString> m_userDescription;
|
||||
caf::PdmPtrField<RimSeismicData*> m_seismicData;
|
||||
caf::PdmPtrField<RimWellPath*> m_wellPath;
|
||||
caf::PdmProxyValueField<QString> m_nameProxy;
|
||||
caf::PdmField<QString> m_userDescription;
|
||||
caf::PdmPtrField<RimSeismicDataInterface*> m_seismicData;
|
||||
caf::PdmPtrField<RimWellPath*> m_wellPath;
|
||||
caf::PdmProxyValueField<QString> m_nameProxy;
|
||||
|
||||
caf::PdmField<caf::AppEnum<RiaDefines::SeismicSectionType>> m_type;
|
||||
caf::PdmChildArrayField<RimPolylineTarget*> m_targets;
|
||||
|
||||
caf::PdmField<double> m_muteDataLimit;
|
||||
caf::PdmField<bool> m_showSeismicOutline;
|
||||
caf::PdmField<bool> m_enablePicking;
|
||||
caf::PdmField<bool> m_showSectionLine;
|
||||
|
@ -191,7 +191,7 @@ std::vector<RimRegularLegendConfig*> RimSeismicSectionCollection::legendConfigs(
|
||||
{
|
||||
std::vector<RimRegularLegendConfig*> retVals;
|
||||
|
||||
std::set<RimSeismicData*> usedSeisData;
|
||||
std::set<RimSeismicDataInterface*> usedSeisData;
|
||||
|
||||
for ( auto& section : m_seismicSections )
|
||||
{
|
||||
@ -220,7 +220,8 @@ void RimSeismicSectionCollection::updateLegendRangesTextAndVisibility( RiuViewer
|
||||
QString subtitle;
|
||||
if ( section->seismicData() )
|
||||
{
|
||||
subtitle = section->seismicData()->userDescription();
|
||||
subtitle = QString::fromStdString( section->seismicData()->userDescription() );
|
||||
|
||||
const int maxChar = 20;
|
||||
if ( subtitle.size() > maxChar )
|
||||
{
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "qwt_text.h"
|
||||
|
||||
#include "RimRegularLegendConfig.h"
|
||||
#include "RimSeismicData.h"
|
||||
#include "RimSeismicDataInterface.h"
|
||||
#include "RimSeismicSection.h"
|
||||
|
||||
#include <QFont>
|
||||
@ -133,7 +133,7 @@ void RiuSeismicHistogramPanel::applyFontSizes( bool replot )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuSeismicHistogramPanel::showHistogram( caf::PdmObjectHandle* selectedObject )
|
||||
{
|
||||
RimSeismicData* seisData = dynamic_cast<RimSeismicData*>( selectedObject );
|
||||
RimSeismicDataInterface* seisData = dynamic_cast<RimSeismicDataInterface*>( selectedObject );
|
||||
if ( seisData == nullptr )
|
||||
{
|
||||
RimSeismicSection* section = dynamic_cast<RimSeismicSection*>( selectedObject );
|
||||
@ -156,11 +156,19 @@ void RiuSeismicHistogramPanel::showHistogram( caf::PdmObjectHandle* selectedObje
|
||||
}
|
||||
}
|
||||
|
||||
showHistogram( seisData );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuSeismicHistogramPanel::showHistogram( RimSeismicDataInterface* seisData )
|
||||
{
|
||||
if ( seisData == nullptr )
|
||||
{
|
||||
clearPlot();
|
||||
return;
|
||||
}
|
||||
|
||||
setPlotData( seisData->userDescription(), seisData->histogramXvalues(), seisData->histogramYvalues() );
|
||||
setPlotData( QString::fromStdString( seisData->userDescription() ), seisData->histogramXvalues(), seisData->histogramYvalues() );
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
class RiuDockedQwtPlot;
|
||||
class RiuSelectionItem;
|
||||
class RimSeismicDataInterface;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
@ -46,6 +47,7 @@ public:
|
||||
void applyFontSizes( bool replot );
|
||||
|
||||
void showHistogram( caf::PdmObjectHandle* selectedObject );
|
||||
void showHistogram( RimSeismicDataInterface* selectedObject );
|
||||
|
||||
private:
|
||||
QPointer<RiuDockedQwtPlot> m_qwtPlot;
|
||||
|
2
ThirdParty/openzgy
vendored
2
ThirdParty/openzgy
vendored
@ -1 +1 @@
|
||||
Subproject commit 3ebcdf1a91ab9df3dc369d372b19498e6fcb1aa7
|
||||
Subproject commit 2463662b48c220db468df2ba6c8ba7ed314613ae
|
Loading…
Reference in New Issue
Block a user