#4800 WBS: Add parameter track which is off by default (#4816)

* Initial WIP

* Identical results with spreadsheet

* Improved and more robust smoothing by filtering points first

* Improved smoothing and more GUI

* Include mixed-label for smoothing threshold

* Implement WBS parameters track

* Much better alignment of tracks without flickering

* Don't replace user description when dragging and dropping tracks

* Fix missing OBG and SH curves

* Fix curve and track D&D

* Make sure parameter curves aren't WBS curves
This commit is contained in:
Gaute Lindkvist 2019-10-03 14:41:37 +02:00 committed by GitHub
parent 55f0cac713
commit f5b10b4d70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 330 additions and 138 deletions

View File

@ -400,7 +400,7 @@ QString RiaDefines::activeFormationNamesResultName()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wellPathAzimuthResultName()
QString RiaDefines::wbsAzimuthResultName()
{
return "Azimuth";
}
@ -408,7 +408,7 @@ QString RiaDefines::wellPathAzimuthResultName()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wellPathInclinationResultName()
QString RiaDefines::wbsInclinationResultName()
{
return "Inclination";
}
@ -416,7 +416,7 @@ QString RiaDefines::wellPathInclinationResultName()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wellPathPPResultName()
QString RiaDefines::wbsPPResultName()
{
return "PP";
}
@ -424,7 +424,7 @@ QString RiaDefines::wellPathPPResultName()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wellPathSHResultName()
QString RiaDefines::wbsSHResultName()
{
return "SH";
}
@ -432,7 +432,7 @@ QString RiaDefines::wellPathSHResultName()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wellPathOBGResultName()
QString RiaDefines::wbsOBGResultName()
{
return "OBG";
}
@ -440,7 +440,7 @@ QString RiaDefines::wellPathOBGResultName()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wellPathFGResultName()
QString RiaDefines::wbsFGResultName()
{
return "FG";
}
@ -448,17 +448,33 @@ QString RiaDefines::wellPathFGResultName()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wellPathSFGResultName()
QString RiaDefines::wbsSFGResultName()
{
return "SFG";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wbsPoissonParameterName()
{
return "RATIO";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wbsUCSParameterName()
{
return "UCS";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QString> RiaDefines::wellPathAngleResultNames()
{
return {RiaDefines::wellPathAzimuthResultName(), RiaDefines::wellPathInclinationResultName()};
return {wbsAzimuthResultName(), wbsInclinationResultName()};
}
//--------------------------------------------------------------------------------------------------
@ -466,11 +482,15 @@ std::vector<QString> RiaDefines::wellPathAngleResultNames()
//--------------------------------------------------------------------------------------------------
std::vector<QString> RiaDefines::wellPathStabilityResultNames()
{
return {RiaDefines::wellPathFGResultName(),
RiaDefines::wellPathOBGResultName(),
RiaDefines::wellPathPPResultName(),
RiaDefines::wellPathSFGResultName(),
RiaDefines::wellPathSHResultName()};
return {wbsFGResultName(), wbsOBGResultName(), wbsPPResultName(), wbsSFGResultName(), wbsSHResultName()};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QString> RiaDefines::wellPathStabilityParameterNames()
{
return {wbsPoissonParameterName(), wbsUCSParameterName()};
}
//--------------------------------------------------------------------------------------------------

View File

@ -114,17 +114,20 @@ QString mockModelBasicInputCase();
QString activeFormationNamesResultName();
// Well path derived results
QString wellPathAzimuthResultName();
QString wellPathInclinationResultName();
QString wellPathPPResultName();
QString wellPathSHResultName();
QString wellPathOBGResultName();
QString wellPathFGResultName();
QString wellPathSFGResultName();
QString wbsAzimuthResultName();
QString wbsInclinationResultName();
QString wbsPPResultName();
QString wbsSHResultName();
QString wbsOBGResultName();
QString wbsFGResultName();
QString wbsSFGResultName();
QString wbsPoissonParameterName();
QString wbsUCSParameterName();
// List of well path derived results
std::vector<QString> wellPathAngleResultNames();
std::vector<QString> wellPathStabilityResultNames();
std::vector<QString> wellPathStabilityParameterNames();
// Units and conversions
enum DepthUnitType

View File

@ -89,7 +89,7 @@ void RicDeleteWellLogPlotTrackFeature::onActionTriggered( bool isChecked )
for ( RimWellLogPlot* wellLogPlot : alteredWellLogPlots )
{
RiuWellLogPlot* viewWidget = dynamic_cast<RiuWellLogPlot*>( wellLogPlot->viewWidget() );
plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredSize().width() );
plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredWidth() );
wellLogPlot->calculateAvailableDepthRange();
wellLogPlot->updateDepthZoom();
wellLogPlot->uiCapability()->updateConnectedEditors();

View File

@ -120,7 +120,12 @@ void RicNewWellBoreStabilityPlotFeature::onActionTriggered( bool isChecked )
}
{
auto task = progInfo.task( "Creating stability curves track", 75 );
auto task = progInfo.task( "Creating parameters track", 15 );
createParametersTrack( plot, wellPath, geoMechView );
}
{
auto task = progInfo.task( "Creating stability curves track", 60 );
createStabilityCurvesTrack( plot, wellPath, geoMechView );
}
@ -193,6 +198,50 @@ void RicNewWellBoreStabilityPlotFeature::createCasingShoeTrack( RimWellBoreStabi
casingShoeTrack->loadDataAndUpdate();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicNewWellBoreStabilityPlotFeature::createParametersTrack( RimWellBoreStabilityPlot* plot,
RimWellPath* wellPath,
RimGeoMechView* geoMechView )
{
RimWellLogTrack* paramCurvesTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack( false,
"WBS Parameters",
plot );
paramCurvesTrack->setWidthScaleFactor( RimWellLogTrack::WIDE_TRACK );
paramCurvesTrack->setAutoScaleXEnabled( true );
paramCurvesTrack->setTickIntervals( 0.5, 0.05 );
paramCurvesTrack->setXAxisGridVisibility( RimWellLogPlot::AXIS_GRID_MAJOR_AND_MINOR );
paramCurvesTrack->setFormationWellPath( wellPath );
paramCurvesTrack->setFormationCase( geoMechView->geoMechCase() );
paramCurvesTrack->setAnnotationType( RiuPlotAnnotationTool::CURVE_ANNOTATIONS );
paramCurvesTrack->setShowRegionLabels( true );
paramCurvesTrack->setVisible( false );
std::vector<QString> resultNames = RiaDefines::wellPathStabilityParameterNames();
std::vector<cvf::Color3f> colors = {cvf::Color3f::CRIMSON, cvf::Color3f::DARK_YELLOW};
for ( size_t i = 0; i < resultNames.size(); ++i )
{
const QString& resultName = resultNames[i];
RigFemResultAddress resAddr( RIG_WELLPATH_DERIVED, resultName.toStdString(), "" );
RimWellLogExtractionCurve* curve = RicWellLogTools::addWellLogExtractionCurve( paramCurvesTrack,
geoMechView,
wellPath,
nullptr,
-1,
false,
false );
curve->setGeoMechResultAddress( resAddr );
curve->setCurrentTimeStep( geoMechView->currentTimeStep() );
curve->setColor( colors[i % colors.size()] );
curve->setLineThickness( 2 );
curve->loadDataAndUpdate( false );
curve->setAutoNameComponents( false, true, false, false, false );
}
paramCurvesTrack->calculateXZoomRangeAndUpdateQwt();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -233,7 +282,7 @@ void RicNewWellBoreStabilityPlotFeature::createStabilityCurvesTrack( RimWellBore
false );
curve->setGeoMechResultAddress( resAddr );
curve->setCurrentTimeStep( geoMechView->currentTimeStep() );
curve->setCustomName( resultName );
curve->setAutoNameComponents( false, true, false, false, false );
curve->setColor( colors[i % colors.size()] );
curve->setLineThickness( 2 );
curve->loadDataAndUpdate( false );

View File

@ -41,6 +41,7 @@ protected:
private:
void createFormationTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechCase* geoMechCase );
void createCasingShoeTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechCase* geoMechCase );
void createStabilityCurvesTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechCase );
void createParametersTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechView );
void createStabilityCurvesTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechView );
void createAnglesTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechView );
};

View File

@ -68,7 +68,7 @@ void RicNewWellLogPlotTrackFeature::onActionTriggered( bool isChecked )
RiuWellLogPlot* viewWidget = dynamic_cast<RiuWellLogPlot*>( wellLogPlot->viewWidget() );
RicWellLogTools::addWellLogExtractionCurve( plotTrack, nullptr, nullptr, nullptr, -1, true );
plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredSize().width() );
plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredWidth() );
wellLogPlot->updateConnectedEditors();
wellLogPlot->loadDataAndUpdate();
}

View File

@ -114,7 +114,7 @@ void RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot( RimWellLogPlot*
for ( std::set<RimWellLogPlot*>::iterator pIt = srcPlots.begin(); pIt != srcPlots.end(); ++pIt )
{
RiuWellLogPlot* viewWidget = dynamic_cast<RiuWellLogPlot*>( ( *pIt )->viewWidget() );
plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredSize().width() );
plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredWidth() );
( *pIt )->calculateAvailableDepthRange();
( *pIt )->updateTrackNames();
@ -130,7 +130,7 @@ void RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot( RimWellLogPlot*
dstWellLogPlot->insertTrack( tracksToMove[tIdx], insertionStartIndex + tIdx );
}
RiuWellLogPlot* viewWidget = dynamic_cast<RiuWellLogPlot*>( dstWellLogPlot->viewWidget() );
plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredSize().width() );
plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredWidth() );
dstWellLogPlot->updateTrackNames();
dstWellLogPlot->updateTracks();

View File

@ -468,8 +468,8 @@ void RimGeoMechResultDefinition::loadResult()
{
if ( m_geomCase && m_geomCase->geoMechData() )
{
if ( this->resultAddress().fieldName == RiaDefines::wellPathFGResultName().toStdString() ||
this->resultAddress().fieldName == RiaDefines::wellPathSFGResultName().toStdString() )
if ( this->resultAddress().fieldName == RiaDefines::wbsFGResultName().toStdString() ||
this->resultAddress().fieldName == RiaDefines::wbsSFGResultName().toStdString() )
{
RigFemResultAddress stressResAddr( RIG_ELEMENT_NODAL, std::string( "ST" ), "" );
RigFemResultAddress porBarResAddr( RIG_ELEMENT_NODAL, std::string( "POR-Bar" ), "" );
@ -625,6 +625,7 @@ QString RimGeoMechResultDefinition::convertToUiResultFieldName( QString resultFi
if ( resultFieldName == "POR-Bar" ) newName = "POR"; // POR-Bar appear as POR
if ( resultFieldName == "MODULUS" ) newName = "Young's Modulus";
if ( resultFieldName == "RATIO" ) newName = "Poisson's Ratio";
if ( resultFieldName == "UCS" ) newName = "UCS bar/ 100";
return newName;
}

View File

@ -563,6 +563,19 @@ void RimWellLogExtractionCurve::findAndLoadWbsParametersFromLasFiles( const RimW
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogExtractionCurve::setAutoNameComponents(
bool addCaseName, bool addProperty, bool addWellname, bool addTimeStep, bool addDate )
{
m_addCaseNameToCurveName = addCaseName;
m_addPropertyToCurveName = addProperty;
m_addWellNameToCurveName = addWellname;
m_addTimestepToCurveName = addTimeStep;
m_addDateToCurveName = addDate;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -86,6 +86,8 @@ public:
static void findAndLoadWbsParametersFromLasFiles( const RimWellPath* wellPath,
RigGeoMechWellLogExtractor* geomExtractor );
void setAutoNameComponents( bool addCaseName, bool addProperty, bool addWellname, bool addTimeStep, bool addDate );
protected:
QString createCurveAutoName() override;
void onLoadDataAndUpdate( bool updateParentPlot ) override;

View File

@ -362,6 +362,22 @@ std::vector<RimWellLogTrack*> RimWellLogPlot::tracks() const
return m_tracks.childObjects();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimWellLogTrack*> RimWellLogPlot::visibleTracks() const
{
std::vector<RimWellLogTrack*> tracks;
for ( RimWellLogTrack* track : m_tracks() )
{
if ( track->isVisible() )
{
tracks.push_back( track );
}
}
return tracks;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -835,7 +851,10 @@ void RimWellLogPlot::updateTrackNames()
{
for ( size_t tIdx = 0; tIdx < m_tracks.size(); tIdx++ )
{
m_tracks[tIdx]->setDescription( QString( "Track %1" ).arg( tIdx + 1 ) );
QString description = m_tracks[tIdx]->description();
QRegularExpression regexp( "Track \\d+" );
description.replace( regexp, QString( "Track %1" ).arg( tIdx + 1 ) );
m_tracks[tIdx]->setDescription( description );
}
}

View File

@ -105,6 +105,7 @@ public:
RimWellLogTrack* trackByIndex( size_t index ) const;
size_t firstVisibleTrackIndex() const;
std::vector<RimWellLogTrack*> tracks() const;
std::vector<RimWellLogTrack*> visibleTracks() const;
void updateTracks( bool autoScaleXAxis = false );
void updateTrackNames();

View File

@ -1534,6 +1534,14 @@ bool RimWellLogTrack::isVisible()
return m_show;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::setVisible( bool visible )
{
m_show = visible;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -1675,6 +1683,24 @@ std::vector<RimWellLogCurve*> RimWellLogTrack::curvesVector()
return curvesVector;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimWellLogCurve*> RimWellLogTrack::visibleCurvesVector()
{
std::vector<RimWellLogCurve*> curvesVector;
for ( RimWellLogCurve* curve : curves )
{
if ( curve->isCurveVisible() )
{
curvesVector.push_back( curve );
}
}
return curvesVector;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -96,6 +96,7 @@ public:
void setDescription( const QString& description );
bool isVisible();
void setVisible( bool visible );
void addCurve( RimWellLogCurve* curve );
void insertCurve( RimWellLogCurve* curve, size_t index );
void takeOutCurve( RimWellLogCurve* curve );
@ -175,6 +176,7 @@ public:
QString description();
std::vector<RimWellLogCurve*> curvesVector();
std::vector<RimWellLogCurve*> visibleCurvesVector();
void uiOrderingForRftPltFormations( caf::PdmUiOrdering& uiOrdering );
void uiOrderingForXAxisSettings( caf::PdmUiOrdering& uiOrdering );

View File

@ -114,18 +114,26 @@ void RigGeoMechWellLogExtractor::curveData( const RigFemResultAddress& resAddr,
if ( resAddr.resultPosType == RIG_WELLPATH_DERIVED )
{
if ( resAddr.fieldName == RiaDefines::wellPathFGResultName().toStdString() ||
resAddr.fieldName == RiaDefines::wellPathSFGResultName().toStdString() )
if ( resAddr.fieldName == RiaDefines::wbsFGResultName().toStdString() ||
resAddr.fieldName == RiaDefines::wbsSFGResultName().toStdString() )
{
wellBoreWallCurveData( resAddr, frameIndex, values );
return;
}
else if ( resAddr.fieldName == "PP" || resAddr.fieldName == "OBG" || resAddr.fieldName == "SH" )
else if ( resAddr.fieldName == RiaDefines::wbsPoissonParameterName().toStdString() ||
resAddr.fieldName == RiaDefines::wbsUCSParameterName().toStdString() )
{
wellPathParameters( resAddr, frameIndex, values );
}
else if ( resAddr.fieldName == RiaDefines::wbsPPResultName().toStdString() ||
resAddr.fieldName == RiaDefines::wbsOBGResultName().toStdString() ||
resAddr.fieldName == RiaDefines::wbsSHResultName().toStdString() )
{
wellPathScaledCurveData( resAddr, frameIndex, values );
return;
}
else if ( resAddr.fieldName == "Azimuth" || resAddr.fieldName == "Inclination" )
else if ( resAddr.fieldName == RiaDefines::wbsAzimuthResultName().toStdString() ||
resAddr.fieldName == RiaDefines::wbsInclinationResultName().toStdString() )
{
wellPathAngles( resAddr, values );
return;
@ -401,6 +409,13 @@ void RigGeoMechWellLogExtractor::wellPathScaledCurveData( const RigFemResultAddr
averageUnscaledValue = ppSourcePair.first;
}
}
else
{
averageIntersectionValuesToSegmentValue( intersectionIdx,
interpolatedInterfaceValues,
std::numeric_limits<float>::infinity(),
&averageUnscaledValue );
}
( *values )[intersectionIdx] = static_cast<double>( averageUnscaledValue ) / hydroStaticPorePressureBar;
}
@ -419,8 +434,8 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres
std::vector<double>* values )
{
CVF_ASSERT( values );
CVF_ASSERT( resAddr.fieldName == RiaDefines::wellPathFGResultName().toStdString() ||
resAddr.fieldName == RiaDefines::wellPathSFGResultName().toStdString() );
CVF_ASSERT( resAddr.fieldName == RiaDefines::wbsFGResultName().toStdString() ||
resAddr.fieldName == RiaDefines::wbsSFGResultName().toStdString() );
// The result addresses needed
RigFemResultAddress stressResAddr( RIG_ELEMENT_NODAL, "ST", "" );
@ -499,7 +514,7 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres
RigGeoMechBoreHoleStressCalculator sigmaCalculator( wellPathStressDouble, porePressureBar, poissonRatio, ucsBar, 32 );
double resultValue = std::numeric_limits<double>::infinity();
if ( resAddr.fieldName == RiaDefines::wellPathFGResultName().toStdString() )
if ( resAddr.fieldName == RiaDefines::wbsFGResultName().toStdString() )
{
if ( isFGregion && validSegmentStress )
{
@ -508,7 +523,7 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres
}
else
{
CVF_ASSERT( resAddr.fieldName == RiaDefines::wellPathSFGResultName().toStdString() );
CVF_ASSERT( resAddr.fieldName == RiaDefines::wbsSFGResultName().toStdString() );
if ( !isFGregion && validSegmentStress )
{
resultValue = sigmaCalculator.solveStassiDalia();
@ -525,6 +540,43 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigGeoMechWellLogExtractor::wellPathParameters( const RigFemResultAddress& resAddr,
int frameIndex,
std::vector<double>* values )
{
CVF_ASSERT( values );
CVF_ASSERT( resAddr.fieldName == RiaDefines::wbsPoissonParameterName().toStdString() ||
resAddr.fieldName == RiaDefines::wbsUCSParameterName().toStdString() );
RigFemPartResultsCollection* resultCollection = m_caseData->femPartResults();
// Check for element property values
RigFemResultAddress elmResAddr( RIG_ELEMENT, resAddr.fieldName, "" );
std::vector<float> elmPropertyValues = resultCollection->resultValues( elmResAddr, 0, frameIndex );
values->resize( m_intersections.size(), 0.0f );
if ( resAddr.fieldName == RiaDefines::wbsPoissonParameterName().toStdString() )
{
#pragma omp parallel for
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
{
( *values )[intersectionIdx] = calculatePoissonRatioInSegment( intersectionIdx, elmPropertyValues ).first;
}
}
else
{
#pragma omp parallel for
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
{
( *values )[intersectionIdx] = calculateUcsInSegment( intersectionIdx, elmPropertyValues ).first / 100.0;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -113,7 +113,7 @@ private:
void wellPathAngles( const RigFemResultAddress& resAddr, std::vector<double>* values );
void wellPathScaledCurveData( const RigFemResultAddress& resAddr, int frameIndex, std::vector<double>* values );
void wellBoreWallCurveData( const RigFemResultAddress& resAddr, int frameIndex, std::vector<double>* values );
void wellPathParameters( const RigFemResultAddress& resAddr, int frameIndex, std::vector<double>* values );
template <typename T>
T interpolateGridResultValue( RigFemResultPosEnum resultPosType,
const std::vector<T>& gridResultValues,

View File

@ -281,14 +281,14 @@ bool RiuDragDrop::dropMimeData( const QMimeData* data, Qt::DropAction action, in
dropTarget->firstAncestorOrThisOfType( wellLogPlotTrack );
if ( wellLogPlotTrack )
{
return handleWellLogPlotTrackDrop( action, draggedObjects, wellLogPlotTrack );
return handleWellLogPlotTrackDrop( action, draggedObjects, wellLogPlotTrack, row );
}
RimWellLogPlot* wellLogPlot;
dropTarget->firstAncestorOrThisOfType( wellLogPlot );
if ( wellLogPlot )
{
return handleWellLogPlotDrop( action, draggedObjects, wellLogPlot );
return handleWellLogPlotDrop( action, draggedObjects, wellLogPlot, row );
}
RimSummaryCaseCollection* summaryCaseCollection;
@ -381,7 +381,8 @@ bool RiuDragDrop::handleGridCaseGroupDrop( Qt::DropAction action,
//--------------------------------------------------------------------------------------------------
bool RiuDragDrop::handleWellLogPlotTrackDrop( Qt::DropAction action,
caf::PdmObjectGroup& draggedObjects,
RimWellLogTrack* trackTarget )
RimWellLogTrack* trackTarget,
int insertAtPosition )
{
std::vector<RimWellLogFileChannel*> wellLogFileChannels = RiuTypedPdmObjects<RimWellLogFileChannel>::typedObjectsFromGroup(
draggedObjects );
@ -400,7 +401,17 @@ bool RiuDragDrop::handleWellLogPlotTrackDrop( Qt::DropAction action,
{
if ( action == Qt::MoveAction )
{
RicWellLogPlotTrackFeatureImpl::moveCurvesToWellLogPlotTrack( trackTarget, wellLogPlotCurves, nullptr );
RimWellLogCurve* insertAfter = nullptr;
if ( insertAtPosition > 0 )
{
auto visibleCurves = trackTarget->visibleCurvesVector();
if ( !visibleCurves.empty() )
{
int insertAfterPosition = std::min( insertAtPosition - 1, (int)visibleCurves.size() - 1 );
insertAfter = visibleCurves[insertAfterPosition];
}
}
RicWellLogPlotTrackFeatureImpl::moveCurvesToWellLogPlotTrack( trackTarget, wellLogPlotCurves, insertAfter );
return true;
}
}
@ -413,8 +424,7 @@ bool RiuDragDrop::handleWellLogPlotTrackDrop( Qt::DropAction action,
{
RimWellLogPlot* wellLogPlot;
trackTarget->firstAncestorOrThisOfType( wellLogPlot );
RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot( wellLogPlot, wellLogPlotTracks, trackTarget );
return true;
return handleWellLogPlotDrop( action, draggedObjects, wellLogPlot, insertAtPosition );
}
}
@ -426,7 +436,8 @@ bool RiuDragDrop::handleWellLogPlotTrackDrop( Qt::DropAction action,
//--------------------------------------------------------------------------------------------------
bool RiuDragDrop::handleWellLogPlotDrop( Qt::DropAction action,
caf::PdmObjectGroup& draggedObjects,
RimWellLogPlot* wellLogPlotTarget )
RimWellLogPlot* wellLogPlotTarget,
int insertAtPosition )
{
std::vector<RimWellLogTrack*> wellLogPlotTracks = RiuTypedPdmObjects<RimWellLogTrack>::typedObjectsFromGroup(
draggedObjects );
@ -434,7 +445,17 @@ bool RiuDragDrop::handleWellLogPlotDrop( Qt::DropAction action,
{
if ( action == Qt::MoveAction )
{
RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot( wellLogPlotTarget, wellLogPlotTracks, nullptr );
RimWellLogTrack* insertAfter = nullptr;
if ( insertAtPosition > 0 )
{
auto visibleTracks = wellLogPlotTarget->visibleTracks();
if ( !visibleTracks.empty() )
{
int insertAfterPosition = std::min( insertAtPosition - 1, (int)visibleTracks.size() - 1 );
insertAfter = visibleTracks[insertAfterPosition];
}
}
RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot( wellLogPlotTarget, wellLogPlotTracks, insertAfter );
return true;
}
}

View File

@ -62,8 +62,12 @@ private:
RimIdenticalGridCaseGroup* gridCaseGroup );
bool handleWellLogPlotTrackDrop( Qt::DropAction action,
caf::PdmObjectGroup& objectGroup,
RimWellLogTrack* wellLogPlotTrack );
bool handleWellLogPlotDrop( Qt::DropAction action, caf::PdmObjectGroup& objectGroup, RimWellLogPlot* wellLogPlot );
RimWellLogTrack* wellLogPlotTrack,
int insertAtPosition );
bool handleWellLogPlotDrop( Qt::DropAction action,
caf::PdmObjectGroup& objectGroup,
RimWellLogPlot* wellLogPlot,
int insertAtPosition );
bool handleWellLogPlotCurveDrop( Qt::DropAction action,
caf::PdmObjectGroup& objectGroup,
RimWellLogCurve* wellLogPlotCurve );

View File

@ -626,8 +626,7 @@ void RiuPlotMainWindow::addViewer( QWidget* viewer, const RimMdiWindowGeometry&
RiuWellLogPlot* wellLogPlot = dynamic_cast<RiuWellLogPlot*>( viewer );
if ( wellLogPlot )
{
QSize preferredSize = wellLogPlot->preferredSize();
subWindowSize = QSize( preferredSize.width(), m_mdiArea->height() );
subWindowSize = QSize( wellLogPlot->preferredWidth(), m_mdiArea->height() );
}
else
{

View File

@ -37,6 +37,7 @@
#include "qwt_legend.h"
#include "qwt_plot_layout.h"
#include "qwt_scale_draw.h"
#include <QFocusEvent>
#include <QHBoxLayout>
@ -142,17 +143,6 @@ void RiuWellLogPlot::insertTrackPlot( RiuWellLogTrack* trackPlot, size_t index )
legend->contentsWidget()->layout()->setAlignment( Qt::AlignBottom | Qt::AlignHCenter );
m_legends.insert( static_cast<int>( index ), legend );
trackPlot->updateLegend();
if ( trackPlot->isRimTrackVisible() )
{
trackPlot->show();
}
else
{
trackPlot->hide();
}
updateChildrenLayout();
}
@ -202,24 +192,23 @@ void RiuWellLogPlot::setPlotTitle( const QString& plotTitle )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuWellLogPlot::preferredSize() const
int RiuWellLogPlot::preferredWidth() const
{
int titleWidth = 0;
int titleHeight = 0;
if ( m_plotTitle && m_plotTitle->isVisible() )
{
titleWidth = m_plotTitle->width();
titleHeight = m_plotTitle->height() + 10;
}
int sumTrackWidth = 0;
int maxTrackHeight = 0;
for ( QPointer<RiuWellLogTrack> track : m_trackPlots )
{
if ( track->isVisible() )
{
sumTrackWidth += track->width();
maxTrackHeight = std::max( maxTrackHeight, track->height() );
}
return QSize( std::max( titleWidth, sumTrackWidth ), titleHeight + maxTrackHeight );
}
return std::max( titleWidth, sumTrackWidth );
}
//--------------------------------------------------------------------------------------------------
@ -237,34 +226,7 @@ void RiuWellLogPlot::setTitleVisible( bool visible )
void RiuWellLogPlot::updateChildrenLayout()
{
reinsertTracks();
int trackCount = m_trackPlots.size();
int numTracksAlreadyShown = 0;
for ( int tIdx = 0; tIdx < trackCount; ++tIdx )
{
if ( m_plotDefinition->areTrackLegendsVisible() && m_trackPlots[tIdx]->isVisible() )
{
int legendColumns = 1;
if ( m_plotDefinition->areTrackLegendsHorizontal() )
{
legendColumns = 0; // unlimited
}
m_legends[tIdx]->setMaxColumns( legendColumns );
m_legends[tIdx]->show();
m_trackPlots[tIdx]->enableDepthAxisLabelsAndTitle( numTracksAlreadyShown == 0 );
numTracksAlreadyShown++;
}
else
{
m_legends[tIdx]->hide();
}
RiuWellLogTrack* riuTrack = m_trackPlots[tIdx];
m_trackLayout->setColumnStretch( tIdx, riuTrack->widthScaleFactor() );
}
alignCanvasTops();
this->update();
this->repaint();
}
//--------------------------------------------------------------------------------------------------
@ -375,71 +337,84 @@ void RiuWellLogPlot::alignCanvasTops()
{
CVF_ASSERT( m_legends.size() == m_trackPlots.size() );
int maxCanvasOffset = 0;
double maxExtent = 0.0;
for ( int tIdx = 0; tIdx < m_trackPlots.size(); ++tIdx )
{
if ( m_trackPlots[tIdx]->isVisible() )
{
// Hack to align QWT plots. See below.
QRectF canvasRect = m_trackPlots[tIdx]->plotLayout()->canvasRect();
int canvasMargins = m_trackPlots[tIdx]->plotLayout()->canvasMargin( QwtPlot::xTop );
maxCanvasOffset = std::max( maxCanvasOffset, static_cast<int>( canvasRect.top() + canvasMargins ) );
QFont font = m_trackPlots[tIdx]->axisFont( QwtPlot::xTop );
maxExtent = std::max( maxExtent, m_trackPlots[tIdx]->axisScaleDraw( QwtPlot::xTop )->extent( font ) );
}
}
int legendHeight = 0;
for ( int tIdx = 0; tIdx < m_trackPlots.size(); ++tIdx )
{
if ( m_trackPlots[tIdx]->isVisible() )
{
// Hack to align QWT plots which doesn't have an x-axis with the other tracks.
// Since they are missing the axis, QWT will shift them upwards.
// So we shift the plot downwards and resize to match the others.
// TODO: Look into subclassing QwtPlotLayout instead.
QRectF canvasRect = m_trackPlots[tIdx]->plotLayout()->canvasRect();
int canvasMargins = m_trackPlots[tIdx]->plotLayout()->canvasMargin( QwtPlot::xTop );
int myCanvasOffset = static_cast<int>( canvasRect.top() ) + canvasMargins;
int canvasShift = std::max( 0, maxCanvasOffset - myCanvasOffset );
QMargins margins = m_trackPlots[tIdx]->contentsMargins();
margins.setTop( margins.top() + canvasShift );
m_trackPlots[tIdx]->setContentsMargins( margins );
if ( m_legends[tIdx]->isVisible() )
{
legendHeight = std::max( legendHeight, m_legends[tIdx]->heightForWidth( canvasRect.width() ) );
m_trackPlots[tIdx]->axisScaleDraw( QwtPlot::xTop )->setMinimumExtent( maxExtent );
}
}
}
if ( m_plotDefinition->areTrackLegendsVisible() && m_trackLayout->columnCount() > 0 && m_trackLayout->rowCount() > 0 )
{
m_scrollBarLayout->setContentsMargins( 0, legendHeight, 0, 0 );
m_trackLayout->setRowMinimumHeight( 0, legendHeight );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::reinsertTracks()
{
clearTrackLayout();
int visibleIndex = 0;
for ( int tIdx = 0; tIdx < m_trackPlots.size(); ++tIdx )
{
if ( m_trackPlots[tIdx]->isVisible() )
if ( m_trackPlots[tIdx]->isRimTrackVisible() )
{
m_trackLayout->addWidget( m_legends[tIdx], 0, static_cast<int>( visibleIndex ) );
m_trackLayout->addWidget( m_trackPlots[tIdx], 1, static_cast<int>( visibleIndex ) );
m_trackLayout->setRowStretch( 1, 1 );
if ( !m_plotDefinition->areTrackLegendsVisible() )
if ( m_plotDefinition->areTrackLegendsVisible() )
{
m_trackPlots[tIdx]->updateLegend();
int legendColumns = 1;
if ( m_plotDefinition->areTrackLegendsHorizontal() )
{
legendColumns = 0; // unlimited
}
m_legends[tIdx]->setMaxColumns( legendColumns );
m_legends[tIdx]->show();
}
else
{
m_legends[tIdx]->hide();
}
m_trackPlots[tIdx]->enableDepthAxisLabelsAndTitle( visibleIndex == 0 );
m_trackPlots[tIdx]->show();
m_trackLayout->addWidget( m_legends[tIdx], 0, static_cast<int>( visibleIndex ) );
m_trackLayout->addWidget( m_trackPlots[tIdx], 1, static_cast<int>( visibleIndex ) );
m_trackLayout->setColumnStretch( visibleIndex++, m_trackPlots[tIdx]->widthScaleFactor() );
m_trackLayout->setRowStretch( 1, 1 );
visibleIndex++;
}
else
{
m_trackPlots[tIdx]->hide();
m_legends[tIdx]->hide();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::clearTrackLayout()
{
if ( m_trackLayout )
{
QLayoutItem* item;
while ( ( item = m_trackLayout->takeAt( 0 ) ) != 0 )
{
}
QWidget().setLayout( m_trackLayout );
m_trackLayout = new QGridLayout( m_plotFrame );
}
}

View File

@ -63,7 +63,7 @@ public:
void setDepthZoomAndReplot( double minDepth, double maxDepth );
void setPlotTitle( const QString& plotTitle );
virtual QSize preferredSize() const;
int preferredWidth() const;
void setTitleVisible( bool visible );
@ -85,6 +85,7 @@ private:
void updateScrollBar( double minDepth, double maxDepth );
void alignCanvasTops();
void reinsertTracks();
void clearTrackLayout();
private slots:
void slotSetMinDepth( int value );

View File

@ -87,6 +87,9 @@ void RiuWellLogTrack::setDefaults()
axisScaleEngine( QwtPlot::yLeft )->setAttribute( QwtScaleEngine::Floating, true );
setAxisScale( QwtPlot::yLeft, 1000, 0 );
setXRange( 0, 100 );
QFont font = axisFont( QwtPlot::xTop );
int lineHeight = QFontMetrics( font ).height() + axisScaleDraw( QwtPlot::xTop )->tickLength( QwtScaleDiv::MajorTick );
axisScaleDraw( QwtPlot::xTop )->setMinimumExtent( lineHeight );
}
//--------------------------------------------------------------------------------------------------