Commit 62bc563d authored by Julien Malik's avatar Julien Malik
Browse files

MRG

parents 31cb46b8 63d745e0
......@@ -389,8 +389,8 @@ MainWindow::closeEvent( QCloseEvent* event )
assert( Application::ConstInstance()->GetModel()==
Application::ConstInstance()->GetModel< DatasetModel >() );
// Get model.
const DatasetModel* model =
Application::ConstInstance()->GetModel< DatasetModel >();
DatasetModel* model =
Application::Instance()->GetModel< DatasetModel >();
if( model==NULL || !model->IsModified() )
return;
......
......@@ -95,12 +95,20 @@ public:
// Public methods.
public:
/** \brief Constructor. */
BuildContext( const QString& filename =QString(),
int id =-1,
const QString& quicklook =QString() ) :
m_Id( id ),
BuildContext( void* const settings ) :
m_Id( -1 ),
m_Filename(),
m_Quicklook(),
m_Settings( settings )
{
}
/** \brief Constructor. */
BuildContext( const QString& filename ) :
m_Id( -1 ),
m_Filename( filename ),
m_Quicklook( quicklook )
m_Quicklook(),
m_Settings( NULL )
{
}
......@@ -110,6 +118,7 @@ public:
int m_Id;
QString m_Filename;
QString m_Quicklook;
void * const m_Settings;
};
//
......
......@@ -74,6 +74,13 @@ AbstractModel
return false;
}
/*******************************************************************************/
void
AbstractModel
::ClearModified()
{
}
/*******************************************************************************/
/* SLOTS */
/*******************************************************************************/
......
......@@ -108,6 +108,10 @@ public:
*/
virtual bool IsModified() const;
/**
*/
virtual void ClearModified();
/*-[ SIGNALS SECTION ]-----------------------------------------------------*/
//
......
......@@ -72,6 +72,7 @@ namespace mvd
namespace otb
{
/**
* Convert an itk::VariableLengthVector< T2 > into a
* itk::FixedArray< T1, N >.
......@@ -137,6 +138,8 @@ ToVariableLengthVector( itk::FixedArray< T1, N >& a,
const itk::VariableLengthVector< T1 >& v );
} // end namespace 'otb'
/*****************************************************************************/
namespace mvd
{
/**
......@@ -171,6 +174,7 @@ AppendToQStringList( QStringList& qsl,
*
* \return The Unicode converted QString.
*/
inline
QString
FromStdString( const std::string& str );
......@@ -191,6 +195,56 @@ ToStdString( const QString& str );
} // end namespace 'mvd'.
/*****************************************************************************/
namespace mvd
{
/**
* \brief Test condition on all elements in range.
*
* \param first First element of range to test.
* \param last Upper (external) boundary of range to test.
* \param pred Predicate testing element in range.
*
* \return true if predicate is true on all elements in the range
* [first, last[ or if range is empty.
*/
template< typename TInputIterator, typename TUnaryPredicate >
inline
bool
AllOf( TInputIterator first, TInputIterator last, TUnaryPredicate pred );
/**
* \brief Test if any of element in range fulfills condition.
*
* \param first First element of range to test.
* \param last Upper (external) boundary of range to test.
* \param pred Predicate testing element in range.
*
* \return true if predicated is true for, at least, one element in range
* [first, last[. If range is empty, this function returns false.
*/
template< typename TInputIterator, typename TUnaryPredicate >
inline
bool
AnyOf( TInputIterator first, TInputIterator last, TUnaryPredicate pred );
/**
* \brief Test if no element in range fulfills condition.
*
* \param first First element of range to test.
* \param last Upper (external) boundary of range to test.
* \param pred Predicate testing element in range.
*
* \return true if predicated is false for all elements in range [first, last[. If range is empty, this function returns true.
*/
template< typename TInputIterator, typename TUnaryPredicate >
inline
bool
NoneOf( TInputIterator first, TInputIterator last, TUnaryPredicate pred );
} // end namespace 'mvd'.
/*****************************************************************************/
/* INLINE SECTION */
......@@ -318,4 +372,61 @@ ToStdString( const QString& str )
} // end namespace 'mvd'
namespace mvd
{
/*******************************************************************************/
template< typename TInputIterator, typename TUnaryPredicate >
inline
bool
AllOf( TInputIterator first, TInputIterator last, TUnaryPredicate pred )
{
while( first!=last )
{
if( !pred( *first ) )
return false;
++first;
}
return true;
}
/*******************************************************************************/
template< typename TInputIterator, typename TUnaryPredicate >
inline
bool
AnyOf( TInputIterator first, TInputIterator last, TUnaryPredicate pred )
{
while( first!=last )
{
if( pred( *first ) )
return true;
++first;
}
return false;
}
/*******************************************************************************/
template< typename TInputIterator, typename TUnaryPredicate >
inline
bool
NoneOf( TInputIterator first, TInputIterator last, TUnaryPredicate pred )
{
while( first!=last )
{
if( pred( *first ) )
return false;
++first;
}
return true;
}
} // end namespace 'mvd'
#endif // __mvdAlgorithm_h
......@@ -282,11 +282,11 @@ ColorDynamicsController
colorDynamicsWidget->GetChannel( channel );
DefaultImageType::PixelType::ValueType min(
minPx[ settings.RgbChannel( channel ) ]
minPx[ settings.GetRgbChannel( channel ) ]
);
DefaultImageType::PixelType::ValueType max(
maxPx[ settings.RgbChannel( channel ) ]
maxPx[ settings.GetRgbChannel( channel ) ]
);
// Block widget's signals...
......@@ -352,11 +352,11 @@ ColorDynamicsController
colorDynamicsWidget->GetChannel( channel );
DefaultImageType::PixelType::ValueType min(
minPx[ settings.RgbChannel( channel ) ]
minPx[ settings.GetRgbChannel( channel ) ]
);
DefaultImageType::PixelType::ValueType max(
maxPx[ settings.RgbChannel( channel ) ]
maxPx[ settings.GetRgbChannel( channel ) ]
);
// Block widget's signals...
//...but force call to valueChanged() slot to force refresh.
......@@ -435,8 +435,8 @@ ColorDynamicsController
);
*/
ParametersType::ValueType low = settings.DynamicsParam( 2 * channel );
ParametersType::ValueType high = settings.DynamicsParam( 2 * channel + 1 );
ParametersType::ValueType low = settings.GetDynamicsParam( 2 * channel );
ParametersType::ValueType hi = settings.GetDynamicsParam( 2 * channel + 1 );
// Block widget's signals...
//...but force call to valueChanged() slot to force refresh.
......@@ -446,8 +446,8 @@ ColorDynamicsController
colorBandDynWgt->SetLowIntensity( low );
OnLowIntensityChanged( channel, low );
colorBandDynWgt->SetHighIntensity( high );
OnHighIntensityChanged( channel, high );
colorBandDynWgt->SetHighIntensity( hi );
OnHighIntensityChanged( channel, hi );
}
colorBandDynWgt->blockSignals( false );
}
......@@ -537,13 +537,13 @@ ColorDynamicsController
// Calculate quantile intensity.
HistogramModel::MeasurementType intensity =
imageModel->GetHistogramModel()->Quantile(
settings.RgbChannel( channel ),
settings.GetRgbChannel( channel ),
0.01 * value,
BOUND_LOWER
);
// Update quantile intensity in model.
settings.DynamicsParam( 2 * channel ) = intensity;
settings.SetDynamicsParam( 2 * channel, intensity );
// Get color-dynamics widgets.
ColorDynamicsWidget* colorDynWgt = GetWidget< ColorDynamicsWidget >();
......@@ -582,13 +582,13 @@ ColorDynamicsController
// Calculate quantile intensity.
HistogramModel::MeasurementType intensity =
imageModel->GetHistogramModel()->Quantile(
settings.RgbChannel( channel ),
settings.GetRgbChannel( channel ),
0.01 * value,
BOUND_UPPER
);
// Update quantile intensity in model.
settings.DynamicsParam( 2 * channel + 1 ) = intensity;
settings.SetDynamicsParam( 2 * channel + 1, intensity );
// Get color-dynamics widgets.
ColorDynamicsWidget* colorDynWgt = GetWidget< ColorDynamicsWidget >();
......@@ -622,7 +622,7 @@ ColorDynamicsController
assert( imageModel->GetHistogramModel()!=NULL );
// Update parameter value.
imageModel->GetSettings().DynamicsParam( 2 * channel ) = value;
imageModel->GetSettings().SetDynamicsParam( 2 * channel, value );
// Get color-dynamics widgets.
ColorDynamicsWidget* colorDynWgt = GetWidget< ColorDynamicsWidget >();
......@@ -636,7 +636,7 @@ ColorDynamicsController
// Refresh quantile display.
colorBandDynWgt->SetLowQuantile(
100.0 * imageModel->GetHistogramModel()->Percentile(
imageModel->GetSettings().RgbChannel( channel ),
imageModel->GetSettings().GetRgbChannel( channel ),
value,
BOUND_LOWER )
);
......@@ -660,7 +660,7 @@ ColorDynamicsController
assert( imageModel->GetHistogramModel()!=NULL );
// Update parameter value in model.
imageModel->GetSettings().DynamicsParam( 2 * channel + 1 ) = value;
imageModel->GetSettings().SetDynamicsParam( 2 * channel + 1, value );
// Get color-dynamics widgets.
ColorDynamicsWidget* colorDynWgt = GetWidget< ColorDynamicsWidget >();
......@@ -674,7 +674,7 @@ ColorDynamicsController
// Refresh quantile display.
colorBandDynWgt->SetHighQuantile(
100.0 * imageModel->GetHistogramModel()->Percentile(
imageModel->GetSettings().RgbChannel( channel ),
imageModel->GetSettings().GetRgbChannel( channel ),
value,
BOUND_UPPER )
);
......@@ -711,6 +711,7 @@ ColorDynamicsController
emit ModelUpdated();
}
/*******************************************************************************/
void
ColorDynamicsController
::OnApplyAllClicked( RgbaChannel channel, double low, double high )
......@@ -730,7 +731,7 @@ ColorDynamicsController
HistogramModel::MeasurementType lintensity =
imageModel->GetHistogramModel()->Quantile(
settings.RgbChannel( i ),
settings.GetRgbChannel( i ),
0.01 * low,
BOUND_LOWER
);
......@@ -738,14 +739,14 @@ ColorDynamicsController
// Calculate quantile intensity.
HistogramModel::MeasurementType uintensity =
imageModel->GetHistogramModel()->Quantile(
settings.RgbChannel( i ),
settings.GetRgbChannel( i ),
0.01 * high,
BOUND_UPPER
);
// Update quantile intensity in model.
settings.DynamicsParam( 2 * i ) = lintensity;
settings.DynamicsParam( 2 * i + 1 ) = uintensity;
settings.SetDynamicsParam( 2 * i, lintensity );
settings.SetDynamicsParam( 2 * i + 1, uintensity );
// Get color-dynamics widgets.
ColorDynamicsWidget* colorDynWgt = GetWidget< ColorDynamicsWidget >();
......
......@@ -171,7 +171,7 @@ ColorSetupController
RgbaChannel channel = static_cast< RgbaChannel >( i );
VectorImageModel::Settings::ChannelVector::value_type band =
imageModel->GetSettings().RgbChannel( i );
imageModel->GetSettings().GetRgbChannel( i );
// Set current-index of channel.
colorSetupWidget->SetCurrentIndex( channel, band );
......@@ -197,7 +197,7 @@ ColorSetupController
assert( imageModel!=NULL );
// Update channel index.
imageModel->GetSettings().RgbChannel( channel ) = index;
imageModel->GetSettings().SetRgbChannel( channel, index );
// Signal band-index of RGB channel has changed to other
// controllers.
......
......@@ -243,7 +243,7 @@ DatasetDescriptor
QDomText textNode( node.toText() );
// TODO: Manage XML structure errors.
assert( !textNode.isNull() );
textNode.setData(
ContainerToString(
settings->GetDynamicsParams().begin(),
......@@ -251,11 +251,6 @@ DatasetDescriptor
)
);
}
// Dynamics
// TODO: Manage XML structure errors.
// TODO: Set dynamics text here.
// if everything went ok
return true;
}
......@@ -383,10 +378,14 @@ DatasetDescriptor
m_ImagesGroupElement =
rootElt.firstChildElement( TAG_NAMES[ ELEMENT_IMAGES_GROUP ] );
#if 0
qDebug()
<< "Read XML descriptor:\n"
<< m_DomDocument.toByteArray()
<< "\n.";
#else
qDebug() << "XML descriptor has been read.";
#endif
}
/*******************************************************************************/
......@@ -432,16 +431,20 @@ void
DatasetDescriptor
::Write( QIODevice& device ) const
{
#if 0
qDebug()
<< "Writing XML descriptor:\n"
<< m_DomDocument.toByteArray( XML_INDENT )
<< "\n...";
#else
qDebug() << "Writing XML descriptor...";
#endif
// TODO: Check IO device is formatted to UTF-8 data.
if( device.write( m_DomDocument.toByteArray( XML_INDENT ) )==-1 )
throw SystemError();
qDebug() << "Written XML descriptor.";
qDebug() << "XML descriptor has been written.";
}
/*******************************************************************************/
......
......@@ -89,53 +89,51 @@ void
DatasetModel
::ImportImage( const QString& filename, int width, int height )
{
LoadImage( filename, width, height, -1, QString() );
AbstractImageModel::BuildContext context( filename );
LoadImage( context, width, height );
}
/*******************************************************************************/
AbstractImageModel*
DatasetModel
::LoadImage( const QString& filename,
::LoadImage( AbstractImageModel::BuildContext& context,
int width,
int height,
int id,
const QString& quicklook )
int height )
{
// Check input parameters.
assert( (id<0 && quicklook.isEmpty()) ||
(id>=0 && !quicklook.isEmpty()) );
assert( (context.m_Id<0 && context.m_Quicklook.isEmpty()) ||
(context.m_Id>=0 && !context.m_Quicklook.isEmpty()) );
// 1. Instanciate local image model.
VectorImageModel* vectorImageModel = new VectorImageModel( this );
// 2. Safely load data from file.
try
//
// 1.1. Assign new image ID to build-context if first time loading.
// Remember provided ID.
int id = context.m_Id;
// Assign image-model ID to build-context if there is none
// provided but keep provided one to test if it's first time
// import or next time loading of image-model.
if( id<0 )
{
//
// 2.1. Fill-in image-model build-contex with provided id (which
// may be -1 if first-time import of image-model.
AbstractImageModel::BuildContext context( filename, id, quicklook );
// Assign image-model ID to build-context if there is none
// provided but keep provided one to test if it's first time
// import or next time loading of image-model.
if( id<0 )
{
AbstractImageModelList aimList( GetImageModels() );
context.m_Id = aimList.indexOf( vectorImageModel );
AbstractImageModelList aimList( GetImageModels() );
context.m_Id = aimList.indexOf( vectorImageModel );
qDebug()
<< "Generated ID" << context.m_Id
<< "for image-file " << context.m_Filename << ".";
}
qDebug()
<< "Generated ID" << context.m_Id
<< "for image-file " << context.m_Filename << ".";
}
// 2. Safely load data from file.
try
{
//
// 2.2. Set image-model content.
// 2.1. Set image-model content.
// TODO: SetFilename() into VectorImageModel::virtual_BuildModel().
vectorImageModel->SetFilename( context.m_Filename, width, height );
//
// 2.3. Build image-model structure and generate cached data).
// 2.2. Build image-model structure and generate cached data).
vectorImageModel->BuildModel( &context );
assert( vectorImageModel->GetQuicklookModel()!=NULL );
......@@ -143,7 +141,7 @@ DatasetModel
if( id<0 )
{
//
// 2.4a: Add image to Dataset descriptor file...
// 2.3a: Add image to Dataset descriptor file...
m_Descriptor->InsertImageModel(
// ...providing newly calculated image-model ID.
context.m_Id,
......@@ -153,13 +151,12 @@ DatasetModel
);
//
// 2.5a: Force writing descriptor with newly imported image.
WriteDescriptor();
// 2.4a: Force writing descriptor with newly imported image.
Save();
}
//
// 2.6
// Connect rendering-settings updated of image-model to
// 2.5. Connect rendering-settings updated of image-model to
// dataset-model in order to update XML descriptor.
QObject::connect(
vectorImageModel,
......@@ -233,7 +230,7 @@ DatasetModel
// Load image-models from descriptor.
// TODO: Replace DatasetModel::BuildContext() by (width, height).
ParseDescriptor(buildContext);
ParseDescriptor( buildContext );
}
}
......@@ -249,32 +246,32 @@ DatasetModel
imageElt = DatasetDescriptor::NextImageSiblingElement( imageElt ) )
{
// Locals.
int id = -1;
QString filename;
QString quicklook;
VectorImageModel::Settings settings;
AbstractImageModel::BuildContext imageContext( &settings );
// Read image-model descriptor information.
DatasetDescriptor::GetImageModel(
imageElt,
id, filename, &settings, quicklook
imageContext.m_Id,
imageContext.m_Filename,
imageContext.m_Settings,
imageContext.m_Quicklook
);
// Traces.
qDebug()
<< "Input image:"
<< "\nID:" << id
<< "\nfilename:" << filename
<< "\nquicklook:" << quicklook;
<< "\nID:" << imageContext.m_Id
<< "\nfilename:" << imageContext.m_Filename
<< "\nquicklook:" << imageContext.m_Quicklook;
// TODO: 3) Remove WxH for screen best-fit during loading of model!
AbstractImageModel* imageModel = LoadImage(
filename,
context->m_Width, context->m_Height,
id,
quicklook
/* AbstractImageModel* imageModel = */ LoadImage(
imageContext,
context->m_Width, context->m_Height
);
#if 0
// Access vector image-model.
VectorImageModel* vectorImageModel =
qobject_cast< VectorImageModel* >( imageModel );
......@@ -282,6 +279,7 @@ DatasetModel
// Re-assign rendering-settings to image-model.
vectorImageModel->SetSettings( settings );
#endif
}
}
......@@ -310,7 +308,13 @@ DatasetModel
++it )
{
if( ( *it )->IsModified() )
{
const VectorImageModel* vim =
qobject_cast< const VectorImageModel* >( *it );
qDebug() << vim->GetFilename() << "is modified.";
return true;
}
}
// Otherwise, this dataset-model is not modified.
......@@ -320,9 +324,26 @@ DatasetModel
/*******************************************************************************/
void
DatasetModel
::Save() const