2014-05-06 15:39:53 -05:00
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
//
// 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 "RimTernaryLegendConfig.h"
# include "cafPdmUiPushButtonEditor.h"
# include "cafPdmUiTextEditor.h"
# include "RiaApplication.h"
# include "RimReservoirView.h"
# include "RivTernarySaturationOverlayItem.h"
2014-05-06 15:50:49 -05:00
# include <cmath>
2014-05-06 16:29:41 -05:00
# include "cvfqtUtils.h"
2014-05-06 15:50:49 -05:00
2014-05-06 15:39:53 -05:00
CAF_PDM_SOURCE_INIT ( RimTernaryLegendConfig , " RimTernaryLegendConfig " ) ;
namespace caf {
template < >
void AppEnum < RimTernaryLegendConfig : : RangeModeType > : : setUp ( )
{
addItem ( RimTernaryLegendConfig : : AUTOMATIC_ALLTIMESTEPS , " AUTOMATIC_ALLTIMESTEPS " , " Global range " ) ;
addItem ( RimTernaryLegendConfig : : AUTOMATIC_CURRENT_TIMESTEP , " AUTOMATIC_CURRENT_TIMESTEP " , " Local range " ) ;
addItem ( RimTernaryLegendConfig : : USER_DEFINED , " USER_DEFINED_MAX_MIN " , " User defined range " ) ;
setDefault ( RimTernaryLegendConfig : : AUTOMATIC_ALLTIMESTEPS ) ;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimTernaryLegendConfig : : RimTernaryLegendConfig ( )
{
CAF_PDM_InitObject ( " Ternary Legend Definition " , " :/Legend.png " , " " , " " ) ;
CAF_PDM_InitField ( & precision , " Precision " , 2 , " Significant digits " , " " , " The number of significant digits displayed in the legend numbers " , " " ) ;
CAF_PDM_InitField ( & rangeMode , " RangeType " , RangeModeEnum ( USER_DEFINED ) , " Range type " , " " , " Switches between automatic and user defined range on the legend " , " " ) ;
CAF_PDM_InitFieldNoDefault ( & applyLocalMinMax , " m_applyLocalMinMax " , " " , " " , " " , " " ) ;
applyLocalMinMax . setIOWritable ( false ) ;
applyLocalMinMax . setIOReadable ( false ) ;
applyLocalMinMax . setUiEditorTypeName ( caf : : PdmUiPushButtonEditor : : uiEditorTypeName ( ) ) ;
applyLocalMinMax . setUiLabelPosition ( caf : : PdmUiItemInfo : : HIDDEN ) ;
applyLocalMinMax = false ;
CAF_PDM_InitFieldNoDefault ( & applyGlobalMinMax , " m_applyGlobalMinMax " , " " , " " , " " , " " ) ;
applyGlobalMinMax . setIOWritable ( false ) ;
applyGlobalMinMax . setIOReadable ( false ) ;
applyGlobalMinMax . setUiEditorTypeName ( caf : : PdmUiPushButtonEditor : : uiEditorTypeName ( ) ) ;
applyGlobalMinMax . setUiLabelPosition ( caf : : PdmUiItemInfo : : HIDDEN ) ;
applyGlobalMinMax = false ;
CAF_PDM_InitFieldNoDefault ( & applyFullRangeMinMax , " m_applyFullRangeMinMax " , " " , " " , " " , " " ) ;
applyFullRangeMinMax . setIOWritable ( false ) ;
applyFullRangeMinMax . setIOReadable ( false ) ;
applyFullRangeMinMax . setUiEditorTypeName ( caf : : PdmUiPushButtonEditor : : uiEditorTypeName ( ) ) ;
applyFullRangeMinMax . setUiLabelPosition ( caf : : PdmUiItemInfo : : HIDDEN ) ;
applyFullRangeMinMax = false ;
CAF_PDM_InitFieldNoDefault ( & ternaryRangeSummary , " ternaryRangeSummary " , " Range summary " , " " , " " , " " ) ;
ternaryRangeSummary . setUiEditorTypeName ( caf : : PdmUiTextEditor : : uiEditorTypeName ( ) ) ;
ternaryRangeSummary . setUiLabelPosition ( caf : : PdmUiItemInfo : : TOP ) ;
CAF_PDM_InitField ( & userDefinedMaxValueSoil , " UserDefinedMaxSoil " , 1.0 , " Max " , " " , " Min value of the legend " , " " ) ;
CAF_PDM_InitField ( & userDefinedMinValueSoil , " UserDefinedMinSoil " , 0.0 , " Min " , " " , " Max value of the legend " , " " ) ;
CAF_PDM_InitField ( & userDefinedMaxValueSgas , " UserDefinedMaxSgas " , 1.0 , " Max " , " " , " Min value of the legend " , " " ) ;
CAF_PDM_InitField ( & userDefinedMinValueSgas , " UserDefinedMinSgas " , 0.0 , " Min " , " " , " Max value of the legend " , " " ) ;
CAF_PDM_InitField ( & userDefinedMaxValueSwat , " UserDefinedMaxSwat " , 1.0 , " Max " , " " , " Min value of the legend " , " " ) ;
CAF_PDM_InitField ( & userDefinedMinValueSwat , " UserDefinedMinSwat " , 0.0 , " Min " , " " , " Max value of the legend " , " " ) ;
m_globalAutoMin . resize ( 3 , 0.0 ) ;
m_globalAutoMax . resize ( 3 , 1.0 ) ;
m_localAutoMin . resize ( 3 , 0.0 ) ;
m_localAutoMax . resize ( 3 , 1.0 ) ;
recreateLegend ( ) ;
updateLegend ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimTernaryLegendConfig : : ~ RimTernaryLegendConfig ( )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig : : fieldChangedByUi ( const caf : : PdmFieldHandle * changedField , const QVariant & oldValue , const QVariant & newValue )
{
if ( changedField = = & applyLocalMinMax )
{
userDefinedMaxValueSoil = m_localAutoMax [ TERNARY_SOIL_IDX ] ;
userDefinedMinValueSoil = m_localAutoMin [ TERNARY_SOIL_IDX ] ;
userDefinedMaxValueSgas = m_localAutoMax [ TERNARY_SGAS_IDX ] ;
userDefinedMinValueSgas = m_localAutoMin [ TERNARY_SGAS_IDX ] ;
userDefinedMaxValueSwat = m_localAutoMax [ TERNARY_SWAT_IDX ] ;
userDefinedMinValueSwat = m_localAutoMin [ TERNARY_SWAT_IDX ] ;
applyLocalMinMax = false ;
}
else if ( changedField = = & applyGlobalMinMax )
{
userDefinedMaxValueSoil = m_globalAutoMax [ TERNARY_SOIL_IDX ] ;
userDefinedMinValueSoil = m_globalAutoMin [ TERNARY_SOIL_IDX ] ;
userDefinedMaxValueSgas = m_globalAutoMax [ TERNARY_SGAS_IDX ] ;
userDefinedMinValueSgas = m_globalAutoMin [ TERNARY_SGAS_IDX ] ;
userDefinedMaxValueSwat = m_globalAutoMax [ TERNARY_SWAT_IDX ] ;
userDefinedMinValueSwat = m_globalAutoMin [ TERNARY_SWAT_IDX ] ;
applyGlobalMinMax = false ;
}
else if ( changedField = = & applyFullRangeMinMax )
{
userDefinedMaxValueSoil = 1.0 ;
userDefinedMinValueSoil = 0.0 ;
userDefinedMaxValueSgas = 1.0 ;
userDefinedMinValueSgas = 0.0 ;
userDefinedMaxValueSwat = 1.0 ;
userDefinedMinValueSwat = 0.0 ;
applyFullRangeMinMax = false ;
}
updateLabelText ( ) ;
updateLegend ( ) ;
if ( m_reservoirView ) m_reservoirView - > updateCurrentTimeStepAndRedraw ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig : : updateLegend ( )
{
2014-05-06 16:29:41 -05:00
double soilLower = 0.0 ;
double soilUpper = 1.0 ;
double sgasLower = 0.0 ;
double sgasUpper = 1.0 ;
double swatLower = 0.0 ;
double swatUpper = 1.0 ;
ternaryRanges ( soilLower , soilUpper , sgasLower , sgasUpper , swatLower , swatUpper ) ;
cvf : : String soilRange ;
cvf : : String sgasRange ;
cvf : : String swatRange ;
int numberPrecision = 1 ;
{
QString tmpString = QString : : number ( soilLower , ' g ' , numberPrecision ) + " - " + QString : : number ( soilUpper , ' g ' , numberPrecision ) ;
soilRange = cvfqt : : Utils : : toString ( tmpString ) ;
}
{
QString tmpString = QString : : number ( sgasLower , ' g ' , numberPrecision ) + " - " + QString : : number ( sgasUpper , ' g ' , numberPrecision ) ;
sgasRange = cvfqt : : Utils : : toString ( tmpString ) ;
}
{
QString tmpString = QString : : number ( swatLower , ' g ' , numberPrecision ) + " - " + QString : : number ( swatUpper , ' g ' , numberPrecision ) ;
swatRange = cvfqt : : Utils : : toString ( tmpString ) ;
}
if ( ! m_legend . isNull ( ) )
{
m_legend - > setRangeText ( soilRange , sgasRange , swatRange ) ;
}
2014-05-06 15:39:53 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig : : setAutomaticRanges ( TernaryArrayIndex ternaryIndex , double globalMin , double globalMax , double localMin , double localMax )
{
double candidateGlobalAutoMin = roundToNumSignificantDigits ( globalMin , precision ) ;
double candidateGlobalAutoMax = roundToNumSignificantDigits ( globalMax , precision ) ;
double candidateLocalAutoMin = roundToNumSignificantDigits ( localMin , precision ) ;
double candidateLocalAutoMax = roundToNumSignificantDigits ( localMax , precision ) ;
m_globalAutoMin [ ternaryIndex ] = candidateGlobalAutoMin ;
m_globalAutoMax [ ternaryIndex ] = candidateGlobalAutoMax ;
m_localAutoMin [ ternaryIndex ] = candidateLocalAutoMin ;
m_localAutoMax [ ternaryIndex ] = candidateLocalAutoMax ;
updateLabelText ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig : : recreateLegend ( )
{
// Due to possible visualization bug, we need to recreate the legend if the last viewer
// has been removed, (and thus the opengl resources has been deleted) The text in
// the legend disappeared because of this, so workaround: recreate the legend when needed:
cvf : : Font * standardFont = RiaApplication : : instance ( ) - > standardFont ( ) ;
m_legend = new RivTernarySaturationOverlayItem ( standardFont ) ;
m_legend - > setLayout ( cvf : : OverlayItem : : VERTICAL , cvf : : OverlayItem : : BOTTOM_LEFT ) ;
updateLegend ( ) ;
}
//--------------------------------------------------------------------------------------------------
/// Rounding the double value to given number of significant digits
//--------------------------------------------------------------------------------------------------
double RimTernaryLegendConfig : : roundToNumSignificantDigits ( double domainValue , double numSignificantDigits )
{
double absDomainValue = cvf : : Math : : abs ( domainValue ) ;
if ( absDomainValue = = 0.0 )
{
return 0.0 ;
}
double logDecValue = log10 ( absDomainValue ) ;
logDecValue = cvf : : Math : : ceil ( logDecValue ) ;
double factor = pow ( 10.0 , numSignificantDigits - logDecValue ) ;
double tmp = domainValue * factor ;
double integerPart ;
double fraction = modf ( tmp , & integerPart ) ;
if ( cvf : : Math : : abs ( fraction ) > = 0.5 ) ( integerPart > = 0 ) ? integerPart + + : integerPart - - ;
double newDomainValue = integerPart / factor ;
return newDomainValue ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig : : defineUiOrdering ( QString uiConfigName , caf : : PdmUiOrdering & uiOrdering )
{
caf : : PdmUiOrdering * formatGr = uiOrdering . addNewGroup ( " Format " ) ;
formatGr - > add ( & precision ) ;
formatGr - > add ( & rangeMode ) ;
if ( rangeMode = = USER_DEFINED )
{
caf : : PdmUiOrdering * ternaryGroupContainer = uiOrdering . addNewGroup ( " Ternary " ) ;
{
caf : : PdmUiOrdering * ternaryGroup = ternaryGroupContainer - > addNewGroup ( " SOIL " ) ;
ternaryGroup - > add ( & userDefinedMinValueSoil ) ;
ternaryGroup - > add ( & userDefinedMaxValueSoil ) ;
}
{
caf : : PdmUiOrdering * ternaryGroup = ternaryGroupContainer - > addNewGroup ( " SGAS " ) ;
ternaryGroup - > add ( & userDefinedMinValueSgas ) ;
ternaryGroup - > add ( & userDefinedMaxValueSgas ) ;
}
{
caf : : PdmUiOrdering * ternaryGroup = ternaryGroupContainer - > addNewGroup ( " SWAT " ) ;
ternaryGroup - > add ( & userDefinedMinValueSwat ) ;
ternaryGroup - > add ( & userDefinedMaxValueSwat ) ;
}
ternaryGroupContainer - > add ( & applyLocalMinMax ) ;
ternaryGroupContainer - > add ( & applyGlobalMinMax ) ;
ternaryGroupContainer - > add ( & applyFullRangeMinMax ) ;
}
else
{
caf : : PdmUiOrdering * group = uiOrdering . addNewGroup ( " Summary " ) ;
group - > add ( & ternaryRangeSummary ) ;
}
uiOrdering . setForgetRemainingFields ( true ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2014-08-01 01:46:46 -05:00
RivTernarySaturationOverlayItem * RimTernaryLegendConfig : : legend ( )
2014-05-06 15:39:53 -05:00
{
return m_legend . p ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig : : defineEditorAttribute ( const caf : : PdmFieldHandle * field , QString uiConfigName , caf : : PdmUiEditorAttribute * attribute )
{
if ( & applyLocalMinMax = = field )
{
caf : : PdmUiPushButtonEditorAttribute * attrib = dynamic_cast < caf : : PdmUiPushButtonEditorAttribute * > ( attribute ) ;
if ( attrib )
{
attrib - > m_buttonText = " Apply local min/max values " ;
}
}
else if ( & applyGlobalMinMax = = field )
{
caf : : PdmUiPushButtonEditorAttribute * attrib = dynamic_cast < caf : : PdmUiPushButtonEditorAttribute * > ( attribute ) ;
if ( attrib )
{
attrib - > m_buttonText = " Apply global min/max values " ;
}
}
else if ( & applyFullRangeMinMax = = field )
{
caf : : PdmUiPushButtonEditorAttribute * attrib = dynamic_cast < caf : : PdmUiPushButtonEditorAttribute * > ( attribute ) ;
if ( attrib )
{
attrib - > m_buttonText = " Apply full range " ;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig : : ternaryRanges ( double & soilLower , double & soilUpper , double & sgasLower , double & sgasUpper , double & swatLower , double & swatUpper ) const
{
if ( rangeMode ( ) = = AUTOMATIC_CURRENT_TIMESTEP )
{
soilLower = m_localAutoMin [ TERNARY_SOIL_IDX ] ;
soilUpper = m_localAutoMax [ TERNARY_SOIL_IDX ] ;
sgasLower = m_localAutoMin [ TERNARY_SGAS_IDX ] ;
sgasUpper = m_localAutoMax [ TERNARY_SGAS_IDX ] ;
swatLower = m_localAutoMin [ TERNARY_SWAT_IDX ] ;
swatUpper = m_localAutoMax [ TERNARY_SWAT_IDX ] ;
}
else if ( rangeMode ( ) = = AUTOMATIC_ALLTIMESTEPS )
{
soilLower = m_globalAutoMin [ TERNARY_SOIL_IDX ] ;
soilUpper = m_globalAutoMax [ TERNARY_SOIL_IDX ] ;
sgasLower = m_globalAutoMin [ TERNARY_SGAS_IDX ] ;
sgasUpper = m_globalAutoMax [ TERNARY_SGAS_IDX ] ;
swatLower = m_globalAutoMin [ TERNARY_SWAT_IDX ] ;
swatUpper = m_globalAutoMax [ TERNARY_SWAT_IDX ] ;
}
else
{
soilLower = userDefinedMinValueSoil ;
soilUpper = userDefinedMaxValueSoil ;
sgasLower = userDefinedMinValueSgas ;
sgasUpper = userDefinedMaxValueSgas ;
swatLower = userDefinedMinValueSwat ;
swatUpper = userDefinedMaxValueSwat ;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig : : updateLabelText ( )
{
{
userDefinedMinValueSoil . setUiName ( " Min " ) ;
userDefinedMaxValueSoil . setUiName ( " Max " ) ;
if ( m_globalAutoMin [ TERNARY_SOIL_IDX ] ! = cvf : : UNDEFINED_DOUBLE )
{
userDefinedMinValueSoil . setUiName ( QString ( " Min " ) + " ( " + QString : : number ( m_globalAutoMin [ TERNARY_SOIL_IDX ] , ' g ' , precision ) + " ) " ) ;
}
if ( m_globalAutoMax [ TERNARY_SOIL_IDX ] ! = cvf : : UNDEFINED_DOUBLE )
{
userDefinedMaxValueSoil . setUiName ( QString ( " Max " ) + " ( " + QString : : number ( m_globalAutoMax [ TERNARY_SOIL_IDX ] , ' g ' , precision ) + " ) " ) ;
}
}
{
userDefinedMinValueSgas . setUiName ( " Min " ) ;
userDefinedMaxValueSgas . setUiName ( " Max " ) ;
if ( m_globalAutoMin [ TERNARY_SGAS_IDX ] ! = cvf : : UNDEFINED_DOUBLE )
{
userDefinedMinValueSgas . setUiName ( QString ( " Min " ) + " ( " + QString : : number ( m_globalAutoMin [ TERNARY_SGAS_IDX ] , ' g ' , precision ) + " ) " ) ;
}
if ( m_globalAutoMax [ TERNARY_SGAS_IDX ] ! = cvf : : UNDEFINED_DOUBLE )
{
userDefinedMaxValueSgas . setUiName ( QString ( " Max " ) + " ( " + QString : : number ( m_globalAutoMax [ TERNARY_SGAS_IDX ] , ' g ' , precision ) + " ) " ) ;
}
}
{
userDefinedMinValueSwat . setUiName ( " Min " ) ;
userDefinedMaxValueSwat . setUiName ( " Max " ) ;
if ( m_globalAutoMin [ TERNARY_SWAT_IDX ] ! = cvf : : UNDEFINED_DOUBLE )
{
userDefinedMinValueSwat . setUiName ( QString ( " Min " ) + " ( " + QString : : number ( m_globalAutoMin [ TERNARY_SWAT_IDX ] , ' g ' , precision ) + " ) " ) ;
}
if ( m_globalAutoMax [ TERNARY_SWAT_IDX ] ! = cvf : : UNDEFINED_DOUBLE )
{
userDefinedMaxValueSwat . setUiName ( QString ( " Max " ) + " ( " + QString : : number ( m_globalAutoMax [ TERNARY_SWAT_IDX ] , ' g ' , precision ) + " ) " ) ;
}
}
if ( rangeMode = = AUTOMATIC_ALLTIMESTEPS )
{
QString tmpString ;
tmpString = QString ( " SOIL : " ) + QString : : number ( m_globalAutoMin [ TERNARY_SOIL_IDX ] , ' g ' , precision ) + " - " + QString : : number ( m_globalAutoMax [ TERNARY_SOIL_IDX ] , ' g ' , precision ) + " \n " ;
tmpString + = QString ( " SGAS : " ) + QString : : number ( m_globalAutoMin [ TERNARY_SGAS_IDX ] , ' g ' , precision ) + " - " + QString : : number ( m_globalAutoMax [ TERNARY_SGAS_IDX ] , ' g ' , precision ) + " \n " ;
tmpString + = QString ( " SWAT : " ) + QString : : number ( m_globalAutoMin [ TERNARY_SWAT_IDX ] , ' g ' , precision ) + " - " + QString : : number ( m_globalAutoMax [ TERNARY_SWAT_IDX ] , ' g ' , precision ) + " \n " ;
ternaryRangeSummary = tmpString ;
}
else if ( rangeMode = = AUTOMATIC_CURRENT_TIMESTEP )
{
QString tmpString ;
tmpString = QString ( " SOIL : " ) + QString : : number ( m_localAutoMin [ TERNARY_SOIL_IDX ] , ' g ' , precision ) + " - " + QString : : number ( m_localAutoMax [ TERNARY_SOIL_IDX ] , ' g ' , precision ) + " \n " ;
tmpString + = QString ( " SGAS : " ) + QString : : number ( m_localAutoMin [ TERNARY_SGAS_IDX ] , ' g ' , precision ) + " - " + QString : : number ( m_localAutoMax [ TERNARY_SGAS_IDX ] , ' g ' , precision ) + " \n " ;
tmpString + = QString ( " SWAT : " ) + QString : : number ( m_localAutoMin [ TERNARY_SWAT_IDX ] , ' g ' , precision ) + " - " + QString : : number ( m_localAutoMax [ TERNARY_SWAT_IDX ] , ' g ' , precision ) + " \n " ;
ternaryRangeSummary = tmpString ;
}
}