23 #include "qgsmeshmemorydataprovider.h" 
   30 const double D_TRUE = 1.0;
 
   31 const double D_FALSE = 0.0;
 
   32 const double D_NODATA = std::numeric_limits<double>::quiet_NaN();
 
   34 std::shared_ptr<QgsMeshMemoryDatasetGroup> QgsMeshCalcUtils::createMemoryDatasetGroup( 
const QString &datasetGroupName, 
const QgsInterval &relativeTime )
 const 
   36   std::shared_ptr<QgsMeshMemoryDatasetGroup> grp;
 
   37   const QList<int> &indexes = mMeshLayer->datasetGroupsIndexes();
 
   38   for ( 
int groupIndex : indexes )
 
   41     const QString name = meta.
name();
 
   42     if ( name == datasetGroupName )
 
   49       grp = std::make_shared<QgsMeshMemoryDatasetGroup>();
 
   51       grp->setDataType( mOutputType );
 
   53       grp->setName( meta.
name() );
 
   57         for ( 
int index = 0; index < mMeshLayer->datasetCount( groupIndex ); ++index )
 
   62         QgsMeshDatasetIndex datasetIndex = mMeshLayer->datasetIndexAtRelativeTime( relativeTime, groupIndex );
 
   64           grp->addDataset( createMemoryDataset( datasetIndex ) );
 
   77   return createMemoryDataset( grp.
dataType() );
 
   80 std::shared_ptr<QgsMeshMemoryDataset> QgsMeshCalcUtils::createMemoryDataset( 
const QgsMeshDatasetIndex &datasetIndex )
 const 
   83   int groupIndex = datasetIndex.
group();
 
   84   const auto meta = mMeshLayer->datasetGroupMetadata( groupIndex );
 
   90   std::shared_ptr<QgsMeshMemoryDataset> ds = createMemoryDataset( mOutputType );
 
   93   ds->time = dsMeta.
time();
 
   97   QgsMeshDataBlock block = QgsMeshLayerUtils::datasetValues( mMeshLayer, datasetIndex, 0, nativeCount );
 
  100   Q_ASSERT( block.
count() == nativeCount );
 
  107       QVector<double> data =
 
  108         QgsMeshLayerUtils::interpolateFromFacesData(
 
  115       Q_ASSERT( data.size() == resultCount );
 
  116       for ( 
int valueIndex = 0; valueIndex < resultCount; ++valueIndex )
 
  121       QVector<double> buf = block.
values();
 
  122       QVector<double> x( nativeCount );
 
  123       QVector<double> y( nativeCount );
 
  124       for ( 
int value_i = 0; value_i < nativeCount; ++value_i )
 
  126         x[value_i] = buf[2 * value_i];
 
  127         y[value_i] = buf[2 * value_i + 1];
 
  130       QVector<double> dataX =
 
  131         QgsMeshLayerUtils::interpolateFromFacesData(
 
  133           mMeshLayer->nativeMesh(),
 
  134           mMeshLayer->triangularMesh(),
 
  136           mMeshLayer->rendererSettings().scalarSettings( groupIndex ).dataResamplingMethod()
 
  138       Q_ASSERT( dataX.size() == resultCount );
 
  139       QVector<double> dataY =
 
  140         QgsMeshLayerUtils::interpolateFromFacesData(
 
  142           mMeshLayer->nativeMesh(),
 
  143           mMeshLayer->triangularMesh(),
 
  145           mMeshLayer->rendererSettings().scalarSettings( groupIndex ).dataResamplingMethod()
 
  148       Q_ASSERT( dataY.size() == resultCount );
 
  150       for ( 
int value_i = 0; value_i < resultCount; ++value_i )
 
  158     for ( 
int value_i = 0; value_i < resultCount; ++value_i )
 
  159       ds->values[value_i] = block.
value( value_i );
 
  166     for ( 
int value_i = 0; value_i < dp->
faceCount(); ++value_i )
 
  167       ds->active[value_i] = active.
active( value_i );
 
  177   std::shared_ptr<QgsMeshMemoryDataset> ds = std::make_shared<QgsMeshMemoryDataset>();
 
  180     ds->values.resize( mMeshLayer->dataProvider()->vertexCount() );
 
  181     ds->active.resize( mMeshLayer->dataProvider()->faceCount() );
 
  182     memset( ds->active.data(), 1, 
static_cast<size_t>( ds->active.size() ) * 
sizeof( 
int ) );
 
  186     ds->values.resize( mMeshLayer->dataProvider()->faceCount() );
 
  192 QgsMeshCalcUtils:: QgsMeshCalcUtils( 
QgsMeshLayer *layer,
 
  193                                      const QStringList &usedGroupNames,
 
  196   : mMeshLayer( layer )
 
  204   mOutputType = determineResultDataType( layer, usedGroupNames );
 
  216   for ( 
const QString &groupName : usedGroupNames )
 
  218     std::shared_ptr<QgsMeshMemoryDatasetGroup> ds = createMemoryDatasetGroup( groupName );
 
  222     mDatasetGroupMap.insert( groupName, ds );
 
  227   bool timesPopulated = 
false;
 
  228   const QList<std::shared_ptr<QgsMeshMemoryDatasetGroup>> vals = mDatasetGroupMap.values();
 
  229   for ( 
const std::shared_ptr<QgsMeshMemoryDatasetGroup> &ds : vals )
 
  231     if ( ds->datasetCount() == 0 )
 
  237     if ( ds->datasetCount() > 1 )
 
  239       if ( timesPopulated )
 
  241         if ( ds->datasetCount() != mTimes.size() )
 
  248       for ( 
int datasetIndex = 0; datasetIndex < ds->datasetCount(); ++datasetIndex )
 
  250         std::shared_ptr<const QgsMeshMemoryDataset> o = ds->constDataset( datasetIndex );
 
  251         if ( timesPopulated )
 
  261           mTimes.append( o->time );
 
  265       timesPopulated = 
true;
 
  270   if ( mTimes.isEmpty() )
 
  272     mTimes.push_back( 0.0 );
 
  277     for ( QVector<double>::iterator it = mTimes.begin(); it != mTimes.end(); )
 
  281            ( ( *it >= startTime ) && ( *it <= endTime ) ) )
 
  284         it = mTimes.erase( it );
 
  289   for ( 
const std::shared_ptr<QgsMeshMemoryDatasetGroup> &ds : vals )
 
  291     if ( ds->dataType() != mOutputType )
 
  299 QgsMeshCalcUtils::QgsMeshCalcUtils( 
QgsMeshLayer *layer, 
const QStringList &usedGroupNames, 
const QgsInterval &relativeTime )
 
  300   : mMeshLayer( layer )
 
  308   mOutputType = determineResultDataType( layer, usedGroupNames );
 
  322   for ( 
const QString &groupName : usedGroupNames )
 
  324     std::shared_ptr<QgsMeshMemoryDatasetGroup> ds = createMemoryDatasetGroup( groupName, relativeTime );
 
  325     if ( !ds || ds->memoryDatasets.isEmpty() )
 
  328     mDatasetGroupMap.insert( groupName, ds );
 
  331   mTimes.push_back( usedInterval.
hours() );
 
  336 bool  QgsMeshCalcUtils::isValid()
 const 
  346 std::shared_ptr<const QgsMeshMemoryDatasetGroup> QgsMeshCalcUtils::group( 
const QString &datasetName )
 const 
  348   return mDatasetGroupMap[datasetName];
 
  357   std::shared_ptr<QgsMeshMemoryDataset> output = createMemoryDataset( filter );
 
  358   output->time = mTimes[0];
 
  360   const QList<int> faceIndexesForRectangle = triangularMesh()->faceIndexesForRectangle( extent );
 
  361   const QVector<int> trianglesToNativeFaces = triangularMesh()->trianglesToNativeFaces();
 
  365     for ( 
const int faceIndex : faceIndexesForRectangle )
 
  367       const int nativeIndex = trianglesToNativeFaces[faceIndex];
 
  368       const QgsMeshFace face = nativeMesh()->face( nativeIndex );
 
  369       for ( 
const int vertexIndex : face )
 
  371         output->values[vertexIndex].set( D_TRUE );
 
  377     for ( 
const int faceIndex : faceIndexesForRectangle )
 
  379       const int nativeIndex = trianglesToNativeFaces[faceIndex];
 
  380       output->values[nativeIndex].set( D_TRUE );
 
  392   std::shared_ptr<QgsMeshMemoryDataset> output = createMemoryDataset( filter );
 
  393   output->time = mTimes[0];
 
  395   const QVector<QgsMeshVertex> &vertices = triangularMesh()->vertices();
 
  399     int nativeVertexCount = mMeshLayer->dataProvider()->vertexCount();
 
  401     for ( 
int i = 0; i < nativeVertexCount; ++i )
 
  406         output->values[i].set( D_TRUE );
 
  410         output->values[i].set( D_FALSE );
 
  416     const QVector<QgsMeshFace> &triangles = triangularMesh()->triangles();
 
  417     for ( 
int i = 0; i < triangles.size(); ++i )
 
  424         output->values[i].
set( D_TRUE );
 
  428         output->values[i].set( D_FALSE );
 
  435 std::shared_ptr<QgsMeshMemoryDataset>  QgsMeshCalcUtils::number( 
double val, 
double time )
 const 
  437   Q_ASSERT( isValid() );
 
  439   std::shared_ptr<QgsMeshMemoryDataset> output = createMemoryDataset( mOutputType );
 
  443   if ( std::isnan( val ) )
 
  446       memset( output->active.data(), 0, 
static_cast<size_t>( output->active.size() ) * 
sizeof( 
int ) );
 
  450     for ( 
int i = 0; i < output->values.size(); ++i ) 
 
  452       output->values[i].set( val );
 
  461   Q_ASSERT( isValid() );
 
  464   std::shared_ptr<QgsMeshMemoryDataset> output = number( val, mTimes[0] );
 
  471   Q_ASSERT( isValid() );
 
  472   number( group1, 1.0 );
 
  477   Q_ASSERT( isValid() );
 
  478   number( group1, D_NODATA );
 
  482 std::shared_ptr<QgsMeshMemoryDataset>  QgsMeshCalcUtils::copy(
 
  483   std::shared_ptr<const QgsMeshMemoryDataset> dataset0
 
  486   Q_ASSERT( isValid() );
 
  487   Q_ASSERT( dataset0 );
 
  489   std::shared_ptr<QgsMeshMemoryDataset> output = std::make_shared<QgsMeshMemoryDataset>();
 
  490   output->values = dataset0->values; 
 
  491   output->active = dataset0->active; 
 
  492   output->time = dataset0->time;
 
  493   output->valid = dataset0->valid;
 
  499   Q_ASSERT( isValid() );
 
  501   std::shared_ptr<const QgsMeshMemoryDatasetGroup> group2 = group( groupName );
 
  504   if ( group2->datasetCount() == 1 )
 
  507     std::shared_ptr<const QgsMeshMemoryDataset> o0 = group2->constDataset( 0 );
 
  508     std::shared_ptr<QgsMeshMemoryDataset> output = copy( o0 );
 
  513     for ( 
int output_index = 0; output_index < group2->datasetCount(); ++output_index )
 
  515       std::shared_ptr<const QgsMeshMemoryDataset> o0 = group2->constDataset( output_index );
 
  518            ( ( o0->time >= mTimes.first() ) && ( o0->time <= mTimes.last() ) )
 
  521         std::shared_ptr<QgsMeshMemoryDataset> output = copy( o0 );
 
  530   Q_ASSERT( isValid() );
 
  535     std::shared_ptr<QgsMeshMemoryDataset> o = group2.
memoryDatasets[i];
 
  544   Q_ASSERT( isValid() );
 
  550       const std::shared_ptr<QgsMeshMemoryDataset> o0 = group1.
memoryDatasets[0];
 
  554         std::shared_ptr<QgsMeshMemoryDataset> o = copy( o0 );
 
  563 std::shared_ptr<QgsMeshMemoryDataset>  QgsMeshCalcUtils::canditateDataset(
 
  565   int datasetIndex )
 const 
  567   Q_ASSERT( isValid() );
 
  581 std::shared_ptr<const QgsMeshMemoryDataset>  QgsMeshCalcUtils::constCandidateDataset(
 
  583   int datasetIndex )
 const 
  585   Q_ASSERT( isValid() );
 
  599 int  QgsMeshCalcUtils::datasetCount(
 
  603   Q_ASSERT( isValid() );
 
  607     return mTimes.size();
 
  616                               std::function<
double( 
double )> func )
 const 
  618   Q_ASSERT( isValid() );
 
  620   for ( 
int time_index = 0; time_index < group.
datasetCount(); ++time_index )
 
  622     std::shared_ptr<QgsMeshMemoryDataset> output = canditateDataset( group, time_index );
 
  624     for ( 
int n = 0; n < output->values.size(); ++n )
 
  626       double val1 = output->values[n].scalar();
 
  627       double res_val = D_NODATA;
 
  628       if ( !std::isnan( val1 ) )
 
  629         res_val = func( val1 );
 
  630       output->values[n] = res_val;
 
  641                               std::function<
double( 
double, 
double )> func )
 const 
  643   Q_ASSERT( isValid() );
 
  646   expand( group1, group2 );
 
  648   for ( 
int time_index = 0; time_index < datasetCount( group1, group2 ); ++time_index )
 
  650     std::shared_ptr<QgsMeshMemoryDataset> o1 = canditateDataset( group1, time_index );
 
  651     std::shared_ptr<const QgsMeshMemoryDataset> o2 = constCandidateDataset( group2, time_index );
 
  653     for ( 
int n = 0; n < o2->values.size(); ++n )
 
  655       double val1 = o1->values[n].scalar();
 
  656       double val2 = o2->values[n].scalar();
 
  657       double res_val = D_NODATA;
 
  658       if ( !std::isnan( val1 ) && !std::isnan( val2 ) )
 
  659         res_val = func( val1, val2 );
 
  660       o1->values[n] = res_val;
 
  671 void QgsMeshCalcUtils::funcAggr(
 
  673   std::function<
double( QVector<double>& )> func
 
  676   Q_ASSERT( isValid() );
 
  681     output->time = mTimes[0];
 
  682     for ( 
int n = 0; n < mMeshLayer->dataProvider()->vertexCount(); ++n )
 
  684       QVector < double > vals;
 
  685       for ( 
int datasetIndex = 0; datasetIndex < group1.
datasetCount(); ++datasetIndex )
 
  687         const std::shared_ptr<QgsMeshMemoryDataset> o1 = canditateDataset( group1, datasetIndex );
 
  689         double val1 = o1->values[n].scalar();
 
  693         if ( !std::isnan( val1 ) )
 
  695           vals.push_back( val1 );
 
  699       double res_val = D_NODATA;
 
  700       if ( !vals.isEmpty() )
 
  702         res_val = func( vals );
 
  705       output->values[n] = res_val;
 
  718     output->time = mTimes[0];
 
  720     int facesCount = mMeshLayer->dataProvider()->faceCount();
 
  721     output->values.resize( facesCount );
 
  723     for ( 
int n = 0; n < mMeshLayer->dataProvider()->faceCount(); ++n )
 
  725       QVector < double > vals;
 
  726       for ( 
int datasetIndex = 0; datasetIndex < group1.
datasetCount(); ++datasetIndex )
 
  728         const std::shared_ptr<QgsMeshMemoryDataset> o1 = canditateDataset( group1, datasetIndex );
 
  729         double val1 = o1->values[n].scalar();
 
  730         if ( !std::isnan( val1 ) )
 
  732           vals.push_back( val1 );
 
  736       double res_val = D_NODATA;
 
  737       if ( !vals.isEmpty() )
 
  739         res_val = func( vals );
 
  742       output->values[n] = res_val;
 
  753   Q_ASSERT( mMeshLayer->triangularMesh() );
 
  754   return mMeshLayer->triangularMesh();
 
  757 const QgsMesh *QgsMeshCalcUtils::nativeMesh()
 const 
  760   Q_ASSERT( mMeshLayer->nativeMesh() );
 
  761   return mMeshLayer->nativeMesh();
 
  764 void QgsMeshCalcUtils::updateMesh()
 const 
  766   if ( ! mMeshLayer->nativeMesh() )
 
  769     mMeshLayer->updateTriangularMesh();
 
  782   Q_ASSERT( isValid() );
 
  785   expand( trueGroup, condition );
 
  786   expand( trueGroup, falseGroup );
 
  791   for ( 
int time_index = 0; time_index < trueGroup.
datasetCount(); ++time_index )
 
  793     std::shared_ptr<QgsMeshMemoryDataset> true_o = canditateDataset( trueGroup, time_index );
 
  794     std::shared_ptr<const QgsMeshMemoryDataset> false_o = constCandidateDataset( falseGroup, time_index );
 
  795     std::shared_ptr<const QgsMeshMemoryDataset> condition_o = constCandidateDataset( condition, time_index );
 
  796     for ( 
int n = 0; n < true_o->values.size(); ++n )
 
  798       double conditionValue =  condition_o->values[n].scalar();
 
  799       double resultValue = D_NODATA;
 
  800       if ( !std::isnan( conditionValue ) )
 
  803           resultValue = true_o->values[n].scalar();
 
  805           resultValue = false_o->values[n].scalar();
 
  807       true_o->values[n] = resultValue;
 
  814       activate( true_o, condition_o );
 
  822   Q_ASSERT( isValid() );
 
  826     for ( 
int datasetIndex = 0; datasetIndex < group.
datasetCount(); ++datasetIndex )
 
  828       std::shared_ptr<QgsMeshMemoryDataset> o1 = canditateDataset( group, datasetIndex );
 
  836 void QgsMeshCalcUtils::activate(
 
  837   std::shared_ptr<QgsMeshMemoryDataset> dataset,
 
  838   std::shared_ptr<const QgsMeshMemoryDataset> refDataset 
 
  842   Q_ASSERT( isValid() );
 
  846   for ( 
int idx = 0; idx < mMeshLayer->dataProvider()->faceCount(); ++idx )
 
  848     if ( refDataset && !refDataset->active.isEmpty() && ( !refDataset->active[idx] ) )
 
  850       dataset->active[idx] = 
false;
 
  854     if ( !dataset->active[idx] )
 
  861     bool isActive = 
true; 
 
  862     for ( 
int j = 0; j < face.size(); ++j )
 
  864       if ( std::isnan( dataset->values[face[j]].scalar() ) )
 
  870     dataset->active[idx] = isActive;
 
  874 double QgsMeshCalcUtils::ffilter( 
double val1, 
double filter )
 const 
  876   Q_ASSERT( !std::isnan( val1 ) );
 
  884 double QgsMeshCalcUtils::fadd( 
double val1, 
double val2 )
 const 
  886   Q_ASSERT( !std::isnan( val1 ) );
 
  887   Q_ASSERT( !std::isnan( val2 ) );
 
  892 double QgsMeshCalcUtils::fsubtract( 
double val1, 
double val2 )
 const 
  894   Q_ASSERT( !std::isnan( val1 ) );
 
  895   Q_ASSERT( !std::isnan( val2 ) );
 
  900 double QgsMeshCalcUtils::fmultiply( 
double val1, 
double val2 )
 const 
  902   Q_ASSERT( !std::isnan( val1 ) );
 
  903   Q_ASSERT( !std::isnan( val2 ) );
 
  908 double QgsMeshCalcUtils::fdivide( 
double val1, 
double val2 )
 const 
  910   Q_ASSERT( !std::isnan( val1 ) );
 
  911   Q_ASSERT( !std::isnan( val2 ) );
 
  919 double QgsMeshCalcUtils::fpower( 
double val1, 
double val2 )
 const 
  921   Q_ASSERT( !std::isnan( val1 ) );
 
  922   Q_ASSERT( !std::isnan( val2 ) );
 
  923   return pow( val1, val2 );
 
  927 double QgsMeshCalcUtils::fequal( 
double val1, 
double val2 )
 const 
  929   Q_ASSERT( !std::isnan( val1 ) );
 
  930   Q_ASSERT( !std::isnan( val2 ) );
 
  942 double QgsMeshCalcUtils::fnotEqual( 
double val1, 
double val2 )
 const 
  944   Q_ASSERT( !std::isnan( val1 ) );
 
  945   Q_ASSERT( !std::isnan( val2 ) );
 
  957 double QgsMeshCalcUtils::fgreaterThan( 
double val1, 
double val2 )
 const 
  959   Q_ASSERT( !std::isnan( val1 ) );
 
  960   Q_ASSERT( !std::isnan( val2 ) );
 
  972 double QgsMeshCalcUtils::flesserThan( 
double val1, 
double val2 )
 const 
  974   Q_ASSERT( !std::isnan( val1 ) );
 
  975   Q_ASSERT( !std::isnan( val2 ) );
 
  987 double QgsMeshCalcUtils::flesserEqual( 
double val1, 
double val2 )
 const 
  989   Q_ASSERT( !std::isnan( val1 ) );
 
  990   Q_ASSERT( !std::isnan( val2 ) );
 
 1002 double QgsMeshCalcUtils::fgreaterEqual( 
double val1, 
double val2 )
 const 
 1004   Q_ASSERT( !std::isnan( val1 ) );
 
 1005   Q_ASSERT( !std::isnan( val2 ) );
 
 1018 double QgsMeshCalcUtils::flogicalAnd( 
double val1, 
double val2 )
 const 
 1020   Q_ASSERT( !std::isnan( val1 ) );
 
 1021   Q_ASSERT( !std::isnan( val2 ) );
 
 1024   if ( bval1 && bval2 )
 
 1031 double QgsMeshCalcUtils::flogicalOr( 
double val1, 
double val2 )
 const 
 1033   Q_ASSERT( !std::isnan( val1 ) );
 
 1034   Q_ASSERT( !std::isnan( val2 ) );
 
 1037   if ( bval1 || bval2 )
 
 1044 double QgsMeshCalcUtils::flogicalNot( 
double val1 )
 const 
 1046   Q_ASSERT( !std::isnan( val1 ) );
 
 1055 double QgsMeshCalcUtils::fchangeSign( 
double val1 )
 const 
 1057   Q_ASSERT( !std::isnan( val1 ) );
 
 1061 double QgsMeshCalcUtils::fmin( 
double val1, 
double val2 )
 const 
 1063   Q_ASSERT( !std::isnan( val1 ) );
 
 1075 double QgsMeshCalcUtils::fmax( 
double val1, 
double val2 )
 const 
 1077   Q_ASSERT( !std::isnan( val1 ) );
 
 1078   Q_ASSERT( !std::isnan( val2 ) );
 
 1090 double QgsMeshCalcUtils::fabs( 
double val1 )
 const 
 1092   Q_ASSERT( !std::isnan( val1 ) );
 
 1104 double QgsMeshCalcUtils::fsumAggregated( QVector<double> &vals )
 const 
 1106   Q_ASSERT( !vals.contains( D_NODATA ) );
 
 1107   Q_ASSERT( !vals.isEmpty() );
 
 1108   return std::accumulate( vals.begin(), vals.end(), 0.0 );
 
 1111 double QgsMeshCalcUtils::fminimumAggregated( QVector<double> &vals )
 const 
 1113   Q_ASSERT( !vals.contains( D_NODATA ) );
 
 1114   Q_ASSERT( !vals.isEmpty() );
 
 1115   return *std::min_element( vals.begin(), vals.end() );
 
 1118 double QgsMeshCalcUtils::fmaximumAggregated( QVector<double> &vals )
 const 
 1120   Q_ASSERT( !vals.contains( D_NODATA ) );
 
 1121   Q_ASSERT( !vals.isEmpty() );
 
 1122   return *std::max_element( vals.begin(), vals.end() );
 
 1125 double QgsMeshCalcUtils::faverageAggregated( QVector<double> &vals )
 const 
 1127   Q_ASSERT( !vals.contains( D_NODATA ) );
 
 1128   Q_ASSERT( !vals.isEmpty() );
 
 1129   return fsumAggregated( vals ) / vals.size();
 
 1134   return func1( group1, std::bind( & QgsMeshCalcUtils::flogicalNot, 
this, std::placeholders::_1 ) );
 
 1139   return func1( group1, std::bind( & QgsMeshCalcUtils::fchangeSign, 
this, std::placeholders::_1 ) );
 
 1144   return func1( group1, std::bind( & QgsMeshCalcUtils::fabs, 
this, std::placeholders::_1 ) );
 
 1149   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fadd, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1154   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fsubtract, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1159   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fmultiply, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1164   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fdivide, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1169   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fpower, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1174   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fequal, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1179   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fnotEqual, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1184   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fgreaterThan, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1189   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::flesserThan, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1194   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::flesserEqual, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1199   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fgreaterEqual, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1204   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::flogicalAnd, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1209   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::flogicalOr, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1214   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fmin, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1219   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fmax, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1224   QHash<QString, int> names;
 
 1226   for ( 
int groupId : groupIndexes )
 
 1229     const QString name = meta.
name();
 
 1230     names[ name ] = groupId;
 
 1232   for ( 
const QString &datasetGroupName : usedGroupNames )
 
 1234     if ( names.contains( datasetGroupName ) )
 
 1236       int groupId = names.value( datasetGroupName );
 
 1254   populateSpatialFilter( filter, extent );
 
 1255   return func2( group1, filter, std::bind( & QgsMeshCalcUtils::ffilter, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1261   populateMaskFilter( filter, mask );
 
 1262   return func2( group1, filter, std::bind( & QgsMeshCalcUtils::ffilter, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1267   return funcAggr( group1, std::bind( & QgsMeshCalcUtils::fsumAggregated, 
this, std::placeholders::_1 ) );
 
 1272   return funcAggr( group1, std::bind( & QgsMeshCalcUtils::fminimumAggregated, 
this, std::placeholders::_1 ) );
 
 1277   return funcAggr( group1, std::bind( & QgsMeshCalcUtils::fmaximumAggregated, 
this, std::placeholders::_1 ) );
 
 1282   return funcAggr( group1, std::bind( & QgsMeshCalcUtils::faverageAggregated, 
this, std::placeholders::_1 ) );