mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-25 14:40:26 -05:00
Proxy fields usually reads and transforms data from other sources, usually other Pdm fields. This commit disables IO for proxy fields in the constructor. If XML serialization is required, this must be set on the proxy field, like this field.xmlCapability()->setIOWritable(true) field.xmlCapability()->setIOReadable(true)
1130 lines
41 KiB
C++
1130 lines
41 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 "RimSeismicSection.h"
|
|
|
|
#include "RiuMainWindow.h"
|
|
#include "RiuSeismicHistogramPanel.h"
|
|
|
|
#include "Rim3dView.h"
|
|
#include "RimPolylineTarget.h"
|
|
#include "RimRegularLegendConfig.h"
|
|
#include "RimSeismicAlphaMapper.h"
|
|
#include "RimSeismicDataInterface.h"
|
|
#include "RimTools.h"
|
|
#include "RimWellPath.h"
|
|
|
|
#include "WellPathCommands/PointTangentManipulator/RicPolyline3dEditor.h"
|
|
#include "WellPathCommands/RicPolylineTargetsPickEventHandler.h"
|
|
|
|
#include "RigPolyLinesData.h"
|
|
#include "RigTexturedSection.h"
|
|
#include "Well/RigWellPath.h"
|
|
|
|
#include "RivSeismicSectionPartMgr.h"
|
|
|
|
#include "cafCmdFeatureMenuBuilder.h"
|
|
#include "cafPdmUiDoubleSliderEditor.h"
|
|
#include "cafPdmUiPushButtonEditor.h"
|
|
#include "cafPdmUiSliderEditor.h"
|
|
#include "cafPdmUiTableViewEditor.h"
|
|
#include "cafPdmUiTreeOrdering.h"
|
|
|
|
#include "cvfBoundingBox.h"
|
|
#include "cvfScalarMapper.h"
|
|
#include "cvfTextureImage.h"
|
|
#include "cvfVector3.h"
|
|
|
|
#include <zgyaccess/seismicslice.h>
|
|
|
|
#include <QDialog>
|
|
#include <QImage>
|
|
#include <QLayout>
|
|
#include <QMenu>
|
|
#include <QPixmap>
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
|
|
CAF_PDM_SOURCE_INIT( RimSeismicSection, "SeismicSection" );
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimSeismicSection::RimSeismicSection()
|
|
: m_pickTargetsEventHandler( new RicPolylineTargetsPickEventHandler( this ) )
|
|
{
|
|
CAF_PDM_InitObject( "Seismic Section", ":/SeismicSection16x16.png" );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_userDescription, "UserDescription", "Description" );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_nameProxy, "NameProxy", "Name Proxy" );
|
|
m_nameProxy.registerGetMethod( this, &RimSeismicSection::fullName );
|
|
m_nameProxy.uiCapability()->setUiReadOnly( true );
|
|
m_nameProxy.uiCapability()->setUiHidden( true );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_type, "Type", "Type" );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_seismicData, "SeismicData", "Seismic Data" );
|
|
CAF_PDM_InitFieldNoDefault( &m_wellPath, "WellPath", "Well Path" );
|
|
|
|
CAF_PDM_InitField( &m_enablePicking, "EnablePicking", false, "" );
|
|
caf::PdmUiPushButtonEditor::configureEditorLabelHidden( &m_enablePicking );
|
|
|
|
CAF_PDM_InitField( &m_showImage, "ShowImage", false, "" );
|
|
caf::PdmUiPushButtonEditor::configureEditorLabelHidden( &m_showImage );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_targets, "Targets", "Targets" );
|
|
m_targets.uiCapability()->setUiEditorTypeName( caf::PdmUiTableViewEditor::uiEditorTypeName() );
|
|
m_targets.uiCapability()->setUiTreeChildrenHidden( true );
|
|
m_targets.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosition::TOP );
|
|
m_targets.uiCapability()->setCustomContextMenuEnabled( true );
|
|
|
|
CAF_PDM_InitField( &m_inlineIndex, "InlineIndex", -1, "Inline" );
|
|
m_inlineIndex.uiCapability()->setUiEditorTypeName( caf::PdmUiSliderEditor::uiEditorTypeName() );
|
|
CAF_PDM_InitField( &m_xlineIndex, "CrosslineIndex", -1, "Xline" );
|
|
m_xlineIndex.uiCapability()->setUiEditorTypeName( caf::PdmUiSliderEditor::uiEditorTypeName() );
|
|
CAF_PDM_InitField( &m_depthIndex, "DepthIndex", -1, "Depth Slice" );
|
|
m_depthIndex.uiCapability()->setUiEditorTypeName( caf::PdmUiSliderEditor::uiEditorTypeName() );
|
|
|
|
CAF_PDM_InitField( &m_lineThickness, "LineThickness", 1, "Line Thickness" );
|
|
CAF_PDM_InitField( &m_lineColor, "LineColor", cvf::Color3f( cvf::Color3f::WHITE ), "Line Color" );
|
|
CAF_PDM_InitField( &m_showSeismicOutline, "ShowSeismicOutline", false, "Show Seismic Data Outline" );
|
|
CAF_PDM_InitField( &m_showSectionLine, "ShowSectionLine", false, "Show Section Polyline" );
|
|
|
|
CAF_PDM_InitField( &m_transparent, "TransparentSection", false, "Transparent (Use on only one section at a time!)" );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_zFilterType, "DepthFilter", "Depth Filter" );
|
|
CAF_PDM_InitField( &m_zUpperThreshold, "UpperThreshold", -1, "Upper Threshold" );
|
|
m_zUpperThreshold.uiCapability()->setUiEditorTypeName( caf::PdmUiSliderEditor::uiEditorTypeName() );
|
|
CAF_PDM_InitField( &m_zLowerThreshold, "LowerThreshold", -1, "Lower Threshold" );
|
|
m_zLowerThreshold.uiCapability()->setUiEditorTypeName( caf::PdmUiSliderEditor::uiEditorTypeName() );
|
|
|
|
setUi3dEditorTypeName( RicPolyline3dEditor::uiEditorTypeName() );
|
|
|
|
setDeletable( true );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimSeismicSection::~RimSeismicSection()
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimSeismicSection::userDescription()
|
|
{
|
|
return m_userDescription;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::setUserDescription( QString description )
|
|
{
|
|
m_userDescription = description;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
caf::PdmFieldHandle* RimSeismicSection::userDescriptionField()
|
|
{
|
|
return &m_nameProxy;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
|
{
|
|
initSliceRanges();
|
|
|
|
auto genGrp = uiOrdering.addNewGroup( "General" );
|
|
|
|
genGrp->add( &m_userDescription );
|
|
genGrp->add( &m_seismicData );
|
|
|
|
if ( m_seismicData != nullptr )
|
|
{
|
|
genGrp->add( &m_type );
|
|
|
|
if ( m_type() == RiaDefines::SeismicSectionType::SS_POLYLINE )
|
|
{
|
|
auto polyGrp = uiOrdering.addNewGroup( "Polyline Definition" );
|
|
polyGrp->add( &m_targets );
|
|
polyGrp->add( &m_enablePicking );
|
|
}
|
|
else if ( m_type() == RiaDefines::SeismicSectionType::SS_INLINE )
|
|
{
|
|
genGrp->add( &m_inlineIndex );
|
|
}
|
|
else if ( m_type() == RiaDefines::SeismicSectionType::SS_XLINE )
|
|
{
|
|
genGrp->add( &m_xlineIndex );
|
|
}
|
|
else if ( m_type() == RiaDefines::SeismicSectionType::SS_DEPTHSLICE )
|
|
{
|
|
genGrp->add( &m_depthIndex );
|
|
}
|
|
else if ( m_type() == RiaDefines::SeismicSectionType::SS_WELLPATH )
|
|
{
|
|
genGrp->add( &m_wellPath );
|
|
}
|
|
|
|
if ( m_type() != RiaDefines::SeismicSectionType::SS_DEPTHSLICE )
|
|
{
|
|
auto filterGroup = uiOrdering.addNewGroup( "Depth Filter" );
|
|
filterGroup->add( &m_zFilterType );
|
|
|
|
switch ( zFilterType() )
|
|
{
|
|
case RimIntersectionFilterEnum::INTERSECT_FILTER_BELOW:
|
|
m_zUpperThreshold.uiCapability()->setUiName( "Depth" );
|
|
filterGroup->add( &m_zUpperThreshold );
|
|
break;
|
|
|
|
case RimIntersectionFilterEnum::INTERSECT_FILTER_BETWEEN:
|
|
m_zUpperThreshold.uiCapability()->setUiName( "Upper Depth" );
|
|
filterGroup->add( &m_zUpperThreshold );
|
|
m_zLowerThreshold.uiCapability()->setUiName( "Lower Depth" );
|
|
filterGroup->add( &m_zLowerThreshold );
|
|
break;
|
|
|
|
case RimIntersectionFilterEnum::INTERSECT_FILTER_ABOVE:
|
|
m_zLowerThreshold.uiCapability()->setUiName( "Depth" );
|
|
filterGroup->add( &m_zLowerThreshold );
|
|
break;
|
|
|
|
case RimIntersectionFilterEnum::INTERSECT_FILTER_NONE:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
auto expGrp = uiOrdering.addNewGroup( "Experimental" );
|
|
expGrp->setCollapsedByDefault();
|
|
expGrp->add( &m_transparent );
|
|
|
|
auto outlGrp = uiOrdering.addNewGroup( "Outline" );
|
|
outlGrp->add( &m_lineThickness );
|
|
outlGrp->add( &m_lineColor );
|
|
outlGrp->add( &m_showSeismicOutline );
|
|
if ( m_type() == RiaDefines::SeismicSectionType::SS_POLYLINE ) outlGrp->add( &m_showSectionLine );
|
|
|
|
outlGrp->setCollapsedByDefault();
|
|
}
|
|
|
|
if ( ( m_type() != RiaDefines::SeismicSectionType::SS_POLYLINE ) && ( m_type() != RiaDefines::SeismicSectionType::SS_WELLPATH ) )
|
|
{
|
|
uiOrdering.add( &m_showImage );
|
|
}
|
|
|
|
uiOrdering.skipRemainingFields();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= "" */ )
|
|
{
|
|
uiTreeOrdering.skipRemainingChildren();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
|
|
{
|
|
if ( field == &m_enablePicking )
|
|
{
|
|
auto* pbAttribute = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute );
|
|
if ( pbAttribute )
|
|
{
|
|
if ( !m_enablePicking )
|
|
{
|
|
pbAttribute->m_buttonText = "Start Picking Points";
|
|
}
|
|
else
|
|
{
|
|
pbAttribute->m_buttonText = "Stop Picking Points";
|
|
}
|
|
}
|
|
}
|
|
else if ( field == &m_showImage )
|
|
{
|
|
auto* pbAttribute = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute );
|
|
if ( pbAttribute )
|
|
{
|
|
pbAttribute->m_buttonText = "Show Image";
|
|
}
|
|
}
|
|
else if ( field == &m_targets )
|
|
{
|
|
auto tvAttribute = dynamic_cast<caf::PdmUiTableViewEditorAttribute*>( attribute );
|
|
if ( tvAttribute )
|
|
{
|
|
tvAttribute->resizePolicy = caf::PdmUiTableViewEditorAttribute::RESIZE_TO_FIT_CONTENT;
|
|
|
|
if ( m_enablePicking )
|
|
{
|
|
tvAttribute->baseColor.setRgb( 255, 220, 255 );
|
|
tvAttribute->alwaysEnforceResizePolicy = true;
|
|
}
|
|
}
|
|
}
|
|
else if ( ( field == &m_depthIndex ) || ( field == &m_inlineIndex ) || ( field == &m_xlineIndex ) )
|
|
{
|
|
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();
|
|
|
|
if ( field == &m_xlineIndex )
|
|
{
|
|
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();
|
|
}
|
|
sliderAttrib->m_maximum = maxVal;
|
|
sliderAttrib->m_minimum = minVal;
|
|
sliderAttrib->m_step = stepVal;
|
|
}
|
|
}
|
|
}
|
|
else if ( ( field == &m_zUpperThreshold ) || ( field == &m_zLowerThreshold ) )
|
|
{
|
|
auto* sliderAttrib = dynamic_cast<caf::PdmUiSliderEditorAttribute*>( attribute );
|
|
if ( ( sliderAttrib ) && ( m_seismicData != nullptr ) )
|
|
{
|
|
auto bb = m_seismicData->boundingBox();
|
|
if ( bb->isValid() )
|
|
{
|
|
sliderAttrib->m_minimum = -1 * bb->max().z();
|
|
sliderAttrib->m_maximum = -1 * bb->min().z();
|
|
sliderAttrib->m_step = (int)m_seismicData->zStep();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::setSectionType( RiaDefines::SeismicSectionType sectionType )
|
|
{
|
|
m_type = sectionType;
|
|
if ( sectionType == RiaDefines::SeismicSectionType::SS_WELLPATH )
|
|
{
|
|
auto wellpath = RimTools::firstWellPath();
|
|
if ( wellpath != nullptr ) m_wellPath = wellpath;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::enablePicking( bool enable )
|
|
{
|
|
m_enablePicking = enable;
|
|
updateConnectedEditors();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimSeismicSection::pickingEnabled() const
|
|
{
|
|
return m_enablePicking();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
caf::PickEventHandler* RimSeismicSection::pickEventHandler() const
|
|
{
|
|
return m_pickTargetsEventHandler.get();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<RimPolylineTarget*> RimSeismicSection::activeTargets() const
|
|
{
|
|
if ( m_type() != RiaDefines::SeismicSectionType::SS_POLYLINE ) return {};
|
|
|
|
return m_targets.childrenByType();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::insertTarget( const RimPolylineTarget* targetToInsertBefore, RimPolylineTarget* targetToInsert )
|
|
{
|
|
size_t index = m_targets.indexOf( targetToInsertBefore );
|
|
if ( index < m_targets.size() )
|
|
m_targets.insert( index, targetToInsert );
|
|
else
|
|
m_targets.push_back( targetToInsert );
|
|
|
|
updateVisualization();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::addTargetNoUpdate( RimPolylineTarget* target )
|
|
{
|
|
m_targets.push_back( target );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::deleteTarget( RimPolylineTarget* targetToDelete )
|
|
{
|
|
m_targets.removeChild( targetToDelete );
|
|
delete targetToDelete;
|
|
|
|
updateVisualization();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::updateVisualization()
|
|
{
|
|
if ( texturedSection().notNull() ) texturedSection()->setWhatToUpdate( RigTexturedSection::WhatToUpdateEnum::UPDATE_GEOMETRY );
|
|
m_wellPathPoints.clear();
|
|
scheduleViewUpdate();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::initAfterRead()
|
|
{
|
|
if ( m_seismicData != nullptr )
|
|
{
|
|
m_seismicData->legendConfig()->changed.connect( this, &RimSeismicSection::onLegendConfigChanged );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::updateEditorsAndVisualization()
|
|
{
|
|
updateConnectedEditors();
|
|
updateVisualization();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::scheduleViewUpdate()
|
|
{
|
|
auto view = firstAncestorOrThisOfType<Rim3dView>();
|
|
if ( view ) view->scheduleCreateDisplayModelAndRedraw();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
cvf::ref<RigPolyLinesData> RimSeismicSection::polyLinesData() const
|
|
{
|
|
cvf::ref<RigPolyLinesData> pld = new RigPolyLinesData;
|
|
if ( ( m_type() == RiaDefines::SeismicSectionType::SS_POLYLINE ) && m_showSectionLine() )
|
|
{
|
|
std::vector<cvf::Vec3d> line;
|
|
for ( const RimPolylineTarget* target : m_targets )
|
|
{
|
|
line.push_back( target->targetPointXYZ() );
|
|
}
|
|
pld->setPolyLine( line );
|
|
}
|
|
|
|
if ( m_showSeismicOutline() && m_seismicData != nullptr )
|
|
{
|
|
m_seismicData->addSeismicOutline( pld.p() );
|
|
}
|
|
|
|
pld->setLineAppearance( m_lineThickness, m_lineColor, false );
|
|
pld->setZPlaneLock( false, 0.0 );
|
|
|
|
if ( isChecked() )
|
|
{
|
|
pld->setVisibility( true, false );
|
|
}
|
|
else
|
|
{
|
|
pld->setVisibility( false, false );
|
|
}
|
|
|
|
return pld;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RivSeismicSectionPartMgr* RimSeismicSection::partMgr()
|
|
{
|
|
if ( m_sectionPartMgr.isNull() ) m_sectionPartMgr = new RivSeismicSectionPartMgr( this );
|
|
|
|
return m_sectionPartMgr.p();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QList<caf::PdmOptionItemInfo> RimSeismicSection::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
|
|
{
|
|
QList<caf::PdmOptionItemInfo> options;
|
|
|
|
if ( fieldNeedingOptions == &m_seismicData )
|
|
{
|
|
auto view = firstAncestorOrThisOfType<Rim3dView>();
|
|
|
|
if ( view != nullptr ) RimTools::seismicDataOptionItems( &options, view->domainBoundingBox() );
|
|
}
|
|
else if ( fieldNeedingOptions == &m_wellPath )
|
|
{
|
|
RimTools::wellPathOptionItems( &options );
|
|
}
|
|
|
|
return options;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::updateTextureSectionFromPoints( std::vector<cvf::Vec3d> points, double zmin, double zmax )
|
|
{
|
|
const int pointCount = (int)points.size();
|
|
if ( pointCount < 2 )
|
|
{
|
|
m_texturedSection->resize( 0 );
|
|
return;
|
|
}
|
|
|
|
bool valid = m_texturedSection->partsCount() == ( pointCount - 1 );
|
|
if ( !valid ) m_texturedSection->resize( pointCount - 1 );
|
|
|
|
for ( int i = 1, j = 0; i < pointCount; i++, j++ )
|
|
{
|
|
cvf::Vec3d p1 = points[j];
|
|
cvf::Vec3d p2 = points[i];
|
|
|
|
if ( !m_texturedSection->part( j ).isRectValid )
|
|
{
|
|
cvf::Vec3dArray rect;
|
|
rect.resize( 4 );
|
|
rect[0].set( p1.x(), p1.y(), -zmax );
|
|
rect[1].set( p2.x(), p2.y(), -zmax );
|
|
rect[2].set( p2.x(), p2.y(), -zmin );
|
|
rect[3].set( p1.x(), p1.y(), -zmin );
|
|
|
|
m_texturedSection->setSectionPartRect( j, rect );
|
|
}
|
|
|
|
if ( m_texturedSection->part( j ).sliceData == nullptr )
|
|
{
|
|
m_texturedSection->setSectionPartData( j, m_seismicData->sliceData( p1.x(), p1.y(), p2.x(), p2.y(), zmin, zmax ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
cvf::ref<RigTexturedSection> RimSeismicSection::texturedSection()
|
|
{
|
|
if ( m_texturedSection.isNull() ) m_texturedSection = new RigTexturedSection();
|
|
|
|
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;
|
|
|
|
double zmin = upperFilterZ( m_seismicData->zMin() );
|
|
double zmax = lowerFilterZ( m_seismicData->zMax() );
|
|
|
|
if ( zmax <= zmin ) return m_texturedSection;
|
|
|
|
if ( m_type() == RiaDefines::SeismicSectionType::SS_POLYLINE )
|
|
{
|
|
if ( m_targets.empty() ) return m_texturedSection;
|
|
|
|
std::vector<cvf::Vec3d> points;
|
|
|
|
for ( int i = 0; i < (int)m_targets.size(); i++ )
|
|
{
|
|
points.push_back( m_targets[i]->targetPointXYZ() );
|
|
}
|
|
updateTextureSectionFromPoints( points, zmin, zmax );
|
|
}
|
|
else if ( m_type() == RiaDefines::SeismicSectionType::SS_WELLPATH )
|
|
{
|
|
if ( m_wellPath() == nullptr ) return m_texturedSection;
|
|
|
|
if ( m_wellPathPoints.empty() )
|
|
{
|
|
m_wellPathPoints = wellPathToSectionPoints( m_wellPath()->wellPathGeometry(), zmin );
|
|
}
|
|
|
|
if ( m_wellPathPoints.empty() ) return m_texturedSection;
|
|
|
|
updateTextureSectionFromPoints( m_wellPathPoints, zmin, zmax );
|
|
}
|
|
else if ( m_type() == RiaDefines::SeismicSectionType::SS_INLINE )
|
|
{
|
|
bool valid = m_texturedSection->partsCount() == 1;
|
|
if ( valid )
|
|
valid = m_texturedSection->part( 0 ).isRectValid;
|
|
else
|
|
m_texturedSection->resize( 1 );
|
|
|
|
int ilStart = m_inlineIndex();
|
|
|
|
if ( !valid )
|
|
{
|
|
int xlStart = m_seismicData->xlineMin();
|
|
int xlStop = m_seismicData->xlineMax();
|
|
|
|
cvf::Vec3dArray points;
|
|
points.resize( 4 );
|
|
points[0] = m_seismicData->convertToWorldCoords( ilStart, xlStart, -zmax );
|
|
points[1] = m_seismicData->convertToWorldCoords( ilStart, xlStop, -zmax );
|
|
points[2] = m_seismicData->convertToWorldCoords( ilStart, xlStop, -zmin );
|
|
points[3] = m_seismicData->convertToWorldCoords( ilStart, xlStart, -zmin );
|
|
|
|
m_texturedSection->setSectionPartRect( 0, points );
|
|
}
|
|
|
|
if ( m_texturedSection->part( 0 ).sliceData == nullptr )
|
|
{
|
|
m_texturedSection->setSectionPartData( 0, m_seismicData->sliceData( RiaDefines::SeismicSliceDirection::INLINE, ilStart, zmin, zmax ) );
|
|
}
|
|
}
|
|
else if ( m_type() == RiaDefines::SeismicSectionType::SS_XLINE )
|
|
{
|
|
bool valid = m_texturedSection->partsCount() == 1;
|
|
if ( valid )
|
|
valid = m_texturedSection->part( 0 ).isRectValid;
|
|
else
|
|
m_texturedSection->resize( 1 );
|
|
|
|
int xlStart = m_xlineIndex();
|
|
|
|
if ( !valid )
|
|
{
|
|
int ilStart = m_seismicData->inlineMin();
|
|
int ilStop = m_seismicData->inlineMax();
|
|
|
|
cvf::Vec3dArray points;
|
|
points.resize( 4 );
|
|
points[0] = m_seismicData->convertToWorldCoords( ilStart, xlStart, -zmax );
|
|
points[1] = m_seismicData->convertToWorldCoords( ilStop, xlStart, -zmax );
|
|
points[2] = m_seismicData->convertToWorldCoords( ilStop, xlStart, -zmin );
|
|
points[3] = m_seismicData->convertToWorldCoords( ilStart, xlStart, -zmin );
|
|
|
|
m_texturedSection->setSectionPartRect( 0, points );
|
|
}
|
|
|
|
if ( m_texturedSection->part( 0 ).sliceData == nullptr )
|
|
{
|
|
m_texturedSection->setSectionPartData( 0, m_seismicData->sliceData( RiaDefines::SeismicSliceDirection::XLINE, xlStart, zmin, zmax ) );
|
|
}
|
|
}
|
|
else if ( m_type() == RiaDefines::SeismicSectionType::SS_DEPTHSLICE )
|
|
{
|
|
bool valid = m_texturedSection->partsCount() == 1;
|
|
if ( valid )
|
|
valid = m_texturedSection->part( 0 ).isRectValid;
|
|
else
|
|
m_texturedSection->resize( 1 );
|
|
|
|
int z = m_depthIndex();
|
|
|
|
if ( !valid )
|
|
{
|
|
int ilStart = m_seismicData->inlineMin();
|
|
int ilStop = m_seismicData->inlineMax();
|
|
|
|
int xlStart = m_seismicData->xlineMin();
|
|
int xlStop = m_seismicData->xlineMax();
|
|
|
|
cvf::Vec3dArray points;
|
|
points.resize( 4 );
|
|
points[3] = m_seismicData->convertToWorldCoords( ilStart, xlStart, -z );
|
|
points[2] = m_seismicData->convertToWorldCoords( ilStop, xlStart, -z );
|
|
points[1] = m_seismicData->convertToWorldCoords( ilStop, xlStop, -z );
|
|
points[0] = m_seismicData->convertToWorldCoords( ilStart, xlStop, -z );
|
|
|
|
m_texturedSection->setSectionPartRect( 0, points );
|
|
}
|
|
|
|
if ( m_texturedSection->part( 0 ).sliceData == nullptr )
|
|
{
|
|
m_texturedSection->setSectionPartData( 0, m_seismicData->sliceData( RiaDefines::SeismicSliceDirection::DEPTH, z, zmin, zmax ) );
|
|
}
|
|
}
|
|
|
|
return m_texturedSection;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
|
|
{
|
|
if ( changedField == &m_enablePicking )
|
|
{
|
|
updateConnectedEditors();
|
|
}
|
|
else if ( changedField == &m_showImage )
|
|
{
|
|
if ( m_seismicData == nullptr ) return;
|
|
|
|
QDialog w;
|
|
QLabel l;
|
|
QHBoxLayout layout;
|
|
layout.addWidget( &l );
|
|
w.setLayout( &layout );
|
|
QPixmap i = getImage();
|
|
l.setPixmap( i );
|
|
|
|
w.exec();
|
|
|
|
m_showImage = false;
|
|
}
|
|
else if ( changedField != &m_userDescription )
|
|
{
|
|
RigTexturedSection::WhatToUpdateEnum updateType = RigTexturedSection::WhatToUpdateEnum::UPDATE_NONE;
|
|
|
|
if ( changedField == &m_seismicData )
|
|
{
|
|
RiuMainWindow::instance()->seismicHistogramPanel()->showHistogram( m_seismicData );
|
|
initSliceRanges();
|
|
|
|
PdmObjectHandle* prevValue = oldValue.value<caf::PdmPointer<PdmObjectHandle>>().rawPtr();
|
|
auto prevSeisData = dynamic_cast<RimSeismicDataInterface*>( prevValue );
|
|
if ( prevSeisData != nullptr )
|
|
{
|
|
prevSeisData->legendConfig()->changed.disconnect( this );
|
|
}
|
|
if ( m_seismicData != nullptr )
|
|
m_seismicData->legendConfig()->changed.connect( this, &RimSeismicSection::onLegendConfigChanged );
|
|
|
|
updateType = RigTexturedSection::WhatToUpdateEnum::UPDATE_ALL;
|
|
m_wellPathPoints.clear();
|
|
}
|
|
else if ( ( changedField == &m_type ) || ( changedField == &m_targets ) || ( changedField == &m_depthIndex ) ||
|
|
( changedField == &m_inlineIndex ) || ( changedField == &m_xlineIndex ) || changedField == &m_zFilterType ||
|
|
changedField == &m_zLowerThreshold || changedField == &m_zUpperThreshold )
|
|
{
|
|
updateType = RigTexturedSection::WhatToUpdateEnum::UPDATE_GEOMETRY;
|
|
}
|
|
else if ( changedField == &m_wellPath )
|
|
{
|
|
updateType = RigTexturedSection::WhatToUpdateEnum::UPDATE_GEOMETRY;
|
|
m_wellPathPoints.clear();
|
|
}
|
|
else if ( changedField == &m_transparent )
|
|
{
|
|
updateType = RigTexturedSection::WhatToUpdateEnum::UPDATE_TEXTURE;
|
|
}
|
|
|
|
texturedSection()->setWhatToUpdate( updateType );
|
|
|
|
scheduleViewUpdate();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimSeismicDataInterface* RimSeismicSection::seismicData() const
|
|
{
|
|
return m_seismicData;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::setSeismicData( RimSeismicDataInterface* seisData )
|
|
{
|
|
if ( m_seismicData != nullptr ) m_seismicData->legendConfig()->changed.disconnect( this );
|
|
|
|
m_seismicData = seisData;
|
|
|
|
if ( seisData != nullptr ) m_seismicData->legendConfig()->changed.connect( this, &RimSeismicSection::onLegendConfigChanged );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimRegularLegendConfig* RimSeismicSection::legendConfig() const
|
|
{
|
|
if ( seismicData() != nullptr ) return seismicData()->legendConfig();
|
|
return nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimSeismicAlphaMapper* RimSeismicSection::alphaValueMapper() const
|
|
{
|
|
if ( seismicData() != nullptr ) return seismicData()->alphaValueMapper();
|
|
return nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimSeismicSection::isTransparent() const
|
|
{
|
|
return m_transparent;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::initSliceRanges()
|
|
{
|
|
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();
|
|
|
|
m_inlineIndex = std::clamp( m_inlineIndex(), m_seismicData->inlineMin(), m_seismicData->inlineMax() );
|
|
m_xlineIndex = std::clamp( m_xlineIndex(), m_seismicData->xlineMin(), m_seismicData->xlineMax() );
|
|
m_depthIndex = std::clamp( m_depthIndex(), (int)m_seismicData->zMin(), (int)m_seismicData->zMax() );
|
|
m_zLowerThreshold = std::clamp( m_zLowerThreshold(), (int)m_seismicData->zMin(), (int)m_seismicData->zMax() );
|
|
m_zUpperThreshold = std::clamp( m_zUpperThreshold(), (int)m_seismicData->zMin(), (int)m_seismicData->zMax() );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QPixmap RimSeismicSection::getImage()
|
|
{
|
|
RiaDefines::SeismicSliceDirection sliceDir = RiaDefines::SeismicSliceDirection::INLINE;
|
|
int iStart = m_inlineIndex();
|
|
|
|
if ( m_type() == RiaDefines::SeismicSectionType::SS_XLINE )
|
|
{
|
|
sliceDir = RiaDefines::SeismicSliceDirection::XLINE;
|
|
iStart = m_xlineIndex();
|
|
}
|
|
else if ( m_type() == RiaDefines::SeismicSectionType::SS_DEPTHSLICE )
|
|
{
|
|
sliceDir = RiaDefines::SeismicSliceDirection::DEPTH;
|
|
iStart = m_depthIndex();
|
|
}
|
|
|
|
double zmin = upperFilterZ( m_seismicData->zMin() );
|
|
double zmax = lowerFilterZ( m_seismicData->zMax() );
|
|
|
|
auto data = m_seismicData->sliceData( sliceDir, iStart, zmin, zmax );
|
|
|
|
auto mapper = legendConfig()->scalarMapper();
|
|
|
|
float* pData = data->values();
|
|
|
|
QImage img( data->width(), data->depth(), QImage::Format_RGB888 );
|
|
|
|
for ( int i = 0; i < data->width(); i++ )
|
|
{
|
|
for ( int j = 0; j < data->depth(); j++ )
|
|
{
|
|
auto rgb = mapper->mapToColor( *pData );
|
|
|
|
QColor color( rgb.r(), rgb.g(), rgb.b() );
|
|
img.setPixel( i, j, color.rgb() );
|
|
|
|
pData++;
|
|
}
|
|
}
|
|
|
|
return QPixmap::fromImage( img );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::onLegendConfigChanged( const caf::SignalEmitter* emitter, RimLegendConfigChangeType changeType )
|
|
{
|
|
RigTexturedSection::WhatToUpdateEnum updateType = RigTexturedSection::WhatToUpdateEnum::UPDATE_GEOMETRY;
|
|
|
|
switch ( changeType )
|
|
{
|
|
case RimLegendConfigChangeType::COLORS:
|
|
case RimLegendConfigChangeType::COLOR_MODE:
|
|
updateType = RigTexturedSection::WhatToUpdateEnum::UPDATE_TEXTURE;
|
|
break;
|
|
case RimLegendConfigChangeType::ALL:
|
|
case RimLegendConfigChangeType::RANGE:
|
|
updateType = RigTexturedSection::WhatToUpdateEnum::UPDATE_DATA;
|
|
break;
|
|
case RimLegendConfigChangeType::LEVELS:
|
|
case RimLegendConfigChangeType::NUMBER_FORMAT:
|
|
case RimLegendConfigChangeType::VISIBILITY:
|
|
updateType = RigTexturedSection::WhatToUpdateEnum::UPDATE_NONE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
texturedSection()->setWhatToUpdate( updateType );
|
|
|
|
if ( m_isChecked() ) scheduleViewUpdate();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimIntersectionFilterEnum RimSeismicSection::zFilterType() const
|
|
{
|
|
return m_zFilterType();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::setDepthFilter( RimIntersectionFilterEnum filterType, int upperValue, int lowerValue )
|
|
{
|
|
m_zFilterType = filterType;
|
|
m_zUpperThreshold = upperValue;
|
|
m_zLowerThreshold = lowerValue;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
int RimSeismicSection::alignZValue( int z ) const
|
|
{
|
|
if ( m_seismicData == nullptr ) return z;
|
|
|
|
const int zMin = (int)m_seismicData->zMin();
|
|
const int zStep = (int)m_seismicData->zStep();
|
|
|
|
int alignedZ = ( ( z - zMin ) / zStep );
|
|
alignedZ *= zStep;
|
|
alignedZ += zMin;
|
|
|
|
return alignedZ;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
int RimSeismicSection::upperFilterZ( int upperGridLimit ) const
|
|
{
|
|
int retVal;
|
|
switch ( zFilterType() )
|
|
{
|
|
case RimIntersectionFilterEnum::INTERSECT_FILTER_BELOW:
|
|
case RimIntersectionFilterEnum::INTERSECT_FILTER_BETWEEN:
|
|
retVal = m_zUpperThreshold;
|
|
break;
|
|
|
|
case RimIntersectionFilterEnum::INTERSECT_FILTER_ABOVE:
|
|
case RimIntersectionFilterEnum::INTERSECT_FILTER_NONE:
|
|
default:
|
|
retVal = upperGridLimit;
|
|
break;
|
|
}
|
|
|
|
return alignZValue( retVal );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
int RimSeismicSection::lowerFilterZ( int lowerGridLimit ) const
|
|
{
|
|
int retVal;
|
|
switch ( zFilterType() )
|
|
{
|
|
case RimIntersectionFilterEnum::INTERSECT_FILTER_ABOVE:
|
|
case RimIntersectionFilterEnum::INTERSECT_FILTER_BETWEEN:
|
|
retVal = m_zLowerThreshold;
|
|
break;
|
|
|
|
case RimIntersectionFilterEnum::INTERSECT_FILTER_BELOW:
|
|
case RimIntersectionFilterEnum::INTERSECT_FILTER_NONE:
|
|
default:
|
|
retVal = lowerGridLimit;
|
|
break;
|
|
}
|
|
|
|
return alignZValue( retVal );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimSeismicSection::resultInfoText( cvf::Vec3d worldCoord, int partIndex )
|
|
{
|
|
if ( ( seismicData() == nullptr ) || ( m_texturedSection.isNull() ) || ( partIndex >= m_texturedSection->partsCount() ) )
|
|
{
|
|
return "";
|
|
}
|
|
|
|
auto [iline, xline] = m_seismicData->convertToInlineXline( worldCoord );
|
|
|
|
QString retVal = QString( "Inline: %1\nCrossline: %2\nDepth: %3\n\n" ).arg( iline ).arg( xline ).arg( std::abs( (int)worldCoord[2] ) );
|
|
|
|
if ( m_texturedSection->partsCount() > 1 )
|
|
{
|
|
retVal += QString( "Section part: %1\n\n" ).arg( partIndex + 1 );
|
|
}
|
|
|
|
float val = m_seismicData->valueAt( worldCoord );
|
|
|
|
if ( !std::isnan( val ) )
|
|
{
|
|
retVal += QString( "Value: %1\n\n" ).arg( val );
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<cvf::Vec3d> RimSeismicSection::wellPathToSectionPoints( RigWellPath* wellpath, double zmin )
|
|
{
|
|
if ( wellpath == nullptr ) return {};
|
|
|
|
int currentInline = 0;
|
|
int currentXline = 0;
|
|
|
|
auto& wellpoints = wellpath->wellPathPoints();
|
|
std::vector<cvf::Vec3d> points;
|
|
|
|
for ( auto& p : wellpoints )
|
|
{
|
|
auto [iline, xline] = m_seismicData->convertToInlineXline( p );
|
|
|
|
if ( std::abs( p.z() ) < zmin ) continue;
|
|
|
|
// first point?
|
|
if ( points.empty() )
|
|
{
|
|
points.push_back( p );
|
|
currentInline = iline;
|
|
currentXline = xline;
|
|
continue;
|
|
}
|
|
|
|
// skip points that give same seismic index
|
|
if ( ( currentInline == iline ) && ( currentXline == xline ) ) continue;
|
|
|
|
points.push_back( p );
|
|
currentInline = iline;
|
|
currentXline = xline;
|
|
}
|
|
|
|
// make sure we include the last point
|
|
if ( points.back() != wellpoints.back() ) points.push_back( wellpoints.back() );
|
|
|
|
return points;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimSeismicSection::fullName() const
|
|
{
|
|
QString name = m_userDescription();
|
|
QString prefix;
|
|
|
|
if ( m_type() == RiaDefines::SeismicSectionType::SS_WELLPATH )
|
|
{
|
|
if ( m_wellPath() != nullptr )
|
|
prefix = m_wellPath->name();
|
|
else
|
|
prefix = "Well Path";
|
|
}
|
|
else if ( m_type() == RiaDefines::SeismicSectionType::SS_POLYLINE )
|
|
{
|
|
prefix = "Polyline";
|
|
}
|
|
else if ( m_type() == RiaDefines::SeismicSectionType::SS_INLINE )
|
|
{
|
|
prefix = QString( "Inline [%1]" ).arg( m_inlineIndex() );
|
|
}
|
|
else if ( m_type() == RiaDefines::SeismicSectionType::SS_XLINE )
|
|
{
|
|
prefix = QString( "Xline [%1]" ).arg( m_xlineIndex() );
|
|
}
|
|
else if ( m_type() == RiaDefines::SeismicSectionType::SS_DEPTHSLICE )
|
|
{
|
|
prefix = QString( "Depth Slice [%1]" ).arg( m_depthIndex() );
|
|
}
|
|
|
|
if ( !name.isEmpty() ) return QString( "%1 - %2" ).arg( prefix ).arg( name );
|
|
|
|
return prefix;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::setWellPath( RimWellPath* wellPath )
|
|
{
|
|
m_wellPath = wellPath;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSeismicSection::defineCustomContextMenu( const caf::PdmFieldHandle* fieldNeedingMenu, QMenu* menu, QWidget* fieldEditorWidget )
|
|
{
|
|
caf::CmdFeatureMenuBuilder menuBuilder;
|
|
|
|
menuBuilder << "RicDeletePolylineTargetFeature";
|
|
|
|
menuBuilder.appendToMenu( menu );
|
|
}
|