36   for ( 
int i = 0; i < pipe.
size(); i++ )
 
   45       clone->setInput( mInterfaces.at( i - 1 ) );
 
   47     mInterfaces.append( clone );
 
   48     if ( role != Qgis::RasterPipeInterfaceRole::Unknown )
 
   50       mRoleMap.insert( role, i );
 
   54   mDataDefinedProperties = pipe.mDataDefinedProperties;
 
   59   const auto constMInterfaces = mInterfaces;
 
   66 bool QgsRasterPipe::connect( QVector<QgsRasterInterface *> interfaces )
 
   69   for ( 
int i = 1; i < interfaces.size(); i++ )
 
   71     if ( ! interfaces[i]->setInput( interfaces[i - 1] ) )
 
   76       QgsDebugMsg( QStringLiteral( 
"cannot connect %1 to %2" ).arg( 
typeid( a ).name(), 
typeid( b ).name() ) );
 
   86   QgsDebugMsgLevel( QStringLiteral( 
"insert %1 at %2" ).arg( 
typeid( *interface ).name() ).arg( idx ), 4 );
 
   87   if ( idx > mInterfaces.size() )
 
   89     idx = mInterfaces.size();
 
   93   QVector<QgsRasterInterface *> interfaces = mInterfaces;
 
   95   interfaces.insert( idx, interface );
 
   97   if ( connect( interfaces ) )
 
  100     mInterfaces.insert( idx, interface );
 
  101     setRole( interface, idx );
 
  106     QgsDebugMsgLevel( QStringLiteral( 
"Error inserting pipe %1" ).arg( idx ), 4 );
 
  110   connect( mInterfaces );
 
  116   if ( !interface ) 
return false;
 
  118   QgsDebugMsgLevel( QStringLiteral( 
"replace by %1 at %2" ).arg( 
typeid( *interface ).name() ).arg( idx ), 4 );
 
  119   if ( !checkBounds( idx ) ) 
return false;
 
  123   QVector<QgsRasterInterface *> interfaces = mInterfaces;
 
  125   interfaces[idx] = interface;
 
  126   bool success = 
false;
 
  127   if ( connect( interfaces ) )
 
  130     delete mInterfaces.at( idx );
 
  131     mInterfaces[idx] = interface;
 
  132     setRole( interface, idx );
 
  137   connect( mInterfaces );
 
  145     role = Qgis::RasterPipeInterfaceRole::Provider;
 
  147     role = Qgis::RasterPipeInterfaceRole::Renderer;
 
  149     role = Qgis::RasterPipeInterfaceRole::Resampler;
 
  151     role = Qgis::RasterPipeInterfaceRole::Brightness;
 
  153     role = Qgis::RasterPipeInterfaceRole::HueSaturation;
 
  155     role = Qgis::RasterPipeInterfaceRole::Projector;
 
  157     role = Qgis::RasterPipeInterfaceRole::Nuller;
 
  166   if ( role == Qgis::RasterPipeInterfaceRole::Unknown )
 
  169   mRoleMap.insert( role, idx );
 
  175   if ( role == Qgis::RasterPipeInterfaceRole::Unknown )
 
  178   const int roleIdx{ mRoleMap[role] };
 
  179   mRoleMap.remove( role );
 
  182   const auto roleMapValues {mRoleMap.values()};
 
  183   if ( roleIdx < *std::max_element( roleMapValues.begin(), roleMapValues.end() ) )
 
  185     for ( 
auto it = mRoleMap.cbegin(); it != mRoleMap.cend(); ++it )
 
  187       if ( it.value() > roleIdx )
 
  189         mRoleMap[it.key()] = it.value() - 1;
 
  204   if ( role == Qgis::RasterPipeInterfaceRole::Unknown )
 
  208   if ( mRoleMap.contains( role ) )
 
  212     return replace( mRoleMap.value( role ), interface );
 
  223   int providerIdx = mRoleMap.value( Qgis::RasterPipeInterfaceRole::Provider, -1 );
 
  224   int rendererIdx = mRoleMap.value( Qgis::RasterPipeInterfaceRole::Renderer, -1 );
 
  225   int resamplerIdx = mRoleMap.value( Qgis::RasterPipeInterfaceRole::Resampler, -1 );
 
  226   int brightnessIdx = mRoleMap.value( Qgis::RasterPipeInterfaceRole::Brightness, -1 );
 
  227   int hueSaturationIdx = mRoleMap.value( Qgis::RasterPipeInterfaceRole::HueSaturation, -1 );
 
  229   if ( role == Qgis::RasterPipeInterfaceRole::Provider )
 
  233   else if ( role == Qgis::RasterPipeInterfaceRole::Renderer )
 
  235     idx = providerIdx + 1;
 
  237   else if ( role == Qgis::RasterPipeInterfaceRole::Brightness )
 
  239     idx = std::max( providerIdx, rendererIdx ) + 1;
 
  241   else if ( role == Qgis::RasterPipeInterfaceRole::HueSaturation )
 
  243     idx = std::max( std::max( providerIdx, rendererIdx ), brightnessIdx ) + 1;
 
  245   else if ( role == Qgis::RasterPipeInterfaceRole::Resampler )
 
  247     idx = std::max( std::max( std::max( providerIdx, rendererIdx ), brightnessIdx ), hueSaturationIdx ) + 1;
 
  249   else if ( role == Qgis::RasterPipeInterfaceRole::Projector )
 
  251     idx = std::max( std::max( std::max( std::max( providerIdx, rendererIdx ), brightnessIdx ), hueSaturationIdx ), resamplerIdx )  + 1;
 
  254   return insert( idx, interface );  
 
  260   if ( mRoleMap.contains( role ) )
 
  262     return mInterfaces.value( mRoleMap.value( role ) );
 
  269   return dynamic_cast<QgsRasterDataProvider *
>( interface( Qgis::RasterPipeInterfaceRole::Provider ) );
 
  274   return dynamic_cast<QgsRasterRenderer *
>( interface( Qgis::RasterPipeInterfaceRole::Renderer ) );
 
  289   return dynamic_cast<QgsHueSaturationFilter *
>( interface( Qgis::RasterPipeInterfaceRole::HueSaturation ) );
 
  294   return dynamic_cast<QgsRasterProjector *
>( interface( Qgis::RasterPipeInterfaceRole::Projector ) );
 
  299   return dynamic_cast<QgsRasterNuller *
>( interface( Qgis::RasterPipeInterfaceRole::Nuller ) );
 
  306   if ( !checkBounds( idx ) )
 
  311   QVector<QgsRasterInterface *> interfaces = mInterfaces;
 
  313   interfaces.remove( idx );
 
  314   bool success = 
false;
 
  315   if ( connect( interfaces ) )
 
  318     unsetRole( mInterfaces.at( idx ) );
 
  319     delete mInterfaces.at( idx );
 
  320     mInterfaces.remove( idx );
 
  325     QgsDebugMsgLevel( QStringLiteral( 
"Error removing pipe %1" ).arg( idx ), 4 );
 
  329   connect( mInterfaces );
 
  336   if ( !interface ) 
return false;
 
  338   return remove( mInterfaces.indexOf( interface ) );
 
  343   QgsDebugMsgLevel( QStringLiteral( 
"idx = %1 on = %2" ).arg( idx ).arg( on ), 4 );
 
  344   if ( !checkBounds( idx ) )
 
  349   bool onOrig = mInterfaces.at( idx )->on();
 
  354   mInterfaces.at( idx )->setOn( on );
 
  356   bool success = connect( mInterfaces );
 
  358   mInterfaces.at( idx )->setOn( onOrig );
 
  359   connect( mInterfaces );
 
  365   QgsDebugMsgLevel( QStringLiteral( 
"idx = %1 on = %2" ).arg( idx ).arg( on ), 4 );
 
  366   if ( !checkBounds( idx ) )
 
  369   bool onOrig = mInterfaces.at( idx )->on();
 
  374   mInterfaces.at( idx )->setOn( on );
 
  376   if ( connect( mInterfaces ) )
 
  379   mInterfaces.at( idx )->setOn( onOrig );
 
  380   connect( mInterfaces );
 
  385 bool QgsRasterPipe::checkBounds( 
int idx )
 const 
  387   return !( idx < 0 || idx >= mInterfaces.size() );
 
  392   mResamplingStage = stage;
 
  394   int resamplerIndex = 0;
 
  397     if ( interfaceRole( interface ) == Qgis::RasterPipeInterfaceRole::Resampler )
 
  420       const double prevOpacity = r->opacity();
 
  426         r->setOpacity( opacity );
 
  434 void QgsRasterPipe::initPropertyDefinitions()
 
  436   const QString origin = QStringLiteral( 
"raster" );
 
  446   static std::once_flag initialized;
 
  447   std::call_once( initialized, [ = ]( )
 
  449     initPropertyDefinitions();
 
  451   return sPropertyDefinitions;