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::create( 
const QString &datasetGroupName )
 const 
   36   const auto dp = mMeshLayer->dataProvider();
 
   37   std::shared_ptr<QgsMeshMemoryDatasetGroup> grp;
 
   38   for ( 
int groupIndex = 0; groupIndex < dp->datasetGroupCount(); ++groupIndex )
 
   40     const auto meta = dp->datasetGroupMetadata( groupIndex );
 
   41     const QString name = meta.name();
 
   42     if ( name == datasetGroupName )
 
   49       grp = std::make_shared<QgsMeshMemoryDatasetGroup>();
 
   50       grp->isScalar = meta.isScalar();
 
   51       grp->type = mOutputType;
 
   52       grp->maximum = meta.maximum();
 
   53       grp->minimum = meta.minimum();
 
   54       grp->name = meta.name();
 
   59       for ( 
int datasetIndex = 0; datasetIndex < dp->datasetCount( groupIndex ); ++datasetIndex )
 
   62         const auto dsMeta = dp->datasetMetadata( index );
 
   63         std::shared_ptr<QgsMeshMemoryDataset> ds = create( grp->type );
 
   64         ds->maximum = dsMeta.maximum();
 
   65         ds->minimum = dsMeta.minimum();
 
   66         ds->time = dsMeta.time();
 
   67         ds->valid = dsMeta.isValid();
 
   70         QgsMeshDataBlock block = QgsMeshLayerUtils::datasetValues( mMeshLayer, index, 0, nativeCount );
 
   73         Q_ASSERT( block.
count() == nativeCount );
 
   81             QVector<double> data =
 
   82               QgsMeshLayerUtils::interpolateFromFacesData(
 
   89             Q_ASSERT( data.size() == resultCount );
 
   90             for ( 
int valueIndex = 0; valueIndex < resultCount; ++valueIndex )
 
   95             QVector<double> buf = block.
values();
 
   96             QVector<double> x( nativeCount );
 
   97             QVector<double> y( nativeCount );
 
   98             for ( 
int value_i = 0; value_i < nativeCount; ++value_i )
 
  100               x[value_i] = buf[2 * value_i];
 
  101               y[value_i] = buf[2 * value_i + 1];
 
  104             QVector<double> dataX =
 
  105               QgsMeshLayerUtils::interpolateFromFacesData(
 
  107                 mMeshLayer->nativeMesh(),
 
  108                 mMeshLayer->triangularMesh(),
 
  110                 mMeshLayer->rendererSettings().scalarSettings( groupIndex ).dataResamplingMethod()
 
  112             Q_ASSERT( dataX.size() == resultCount );
 
  113             QVector<double> dataY =
 
  114               QgsMeshLayerUtils::interpolateFromFacesData(
 
  116                 mMeshLayer->nativeMesh(),
 
  117                 mMeshLayer->triangularMesh(),
 
  119                 mMeshLayer->rendererSettings().scalarSettings( groupIndex ).dataResamplingMethod()
 
  122             Q_ASSERT( dataY.size() == resultCount );
 
  124             for ( 
int value_i = 0; value_i < resultCount; ++value_i )
 
  132           for ( 
int value_i = 0; value_i < resultCount; ++value_i )
 
  133             ds->values[value_i] = block.
value( value_i );
 
  138           const QgsMeshDataBlock active = dp->areFacesActive( index, 0, dp->faceCount() );
 
  139           Q_ASSERT( active.
count() == dp->faceCount() );
 
  140           for ( 
int value_i = 0; value_i < dp->faceCount(); ++value_i )
 
  141             ds->active[value_i] = active.
active( value_i );
 
  143         grp->addDataset( ds );
 
  152 std::shared_ptr<QgsMeshMemoryDataset> QgsMeshCalcUtils::create( 
const QgsMeshMemoryDatasetGroup &grp )
 const 
  154   return create( grp.type );
 
  161   std::shared_ptr<QgsMeshMemoryDataset> ds = std::make_shared<QgsMeshMemoryDataset>();
 
  164     ds->values.resize( mMeshLayer->dataProvider()->vertexCount() );
 
  165     ds->active.resize( mMeshLayer->dataProvider()->faceCount() );
 
  166     memset( ds->active.data(), 1, 
static_cast<size_t>( ds->active.size() ) * 
sizeof( 
int ) );
 
  170     ds->values.resize( mMeshLayer->dataProvider()->faceCount() );
 
  176 QgsMeshCalcUtils:: QgsMeshCalcUtils( 
QgsMeshLayer *layer,
 
  177                                      const QStringList &usedGroupNames,
 
  180   : mMeshLayer( layer )
 
  188   mOutputType = determineResultDataType( layer, usedGroupNames );
 
  200   for ( 
const QString &groupName : usedGroupNames )
 
  202     std::shared_ptr<QgsMeshMemoryDatasetGroup> ds = create( groupName );
 
  206     mDatasetGroupMap.insert( groupName, ds );
 
  211   bool timesPopulated = 
false;
 
  212   const auto vals = mDatasetGroupMap.values();
 
  213   for ( 
const auto &ds : vals )
 
  215     if ( ds->datasetCount() == 0 )
 
  221     if ( ds->datasetCount() > 1 )
 
  223       if ( timesPopulated )
 
  225         if ( ds->datasetCount() != mTimes.size() )
 
  232       for ( 
int datasetIndex = 0; datasetIndex < ds->datasetCount(); ++datasetIndex )
 
  234         std::shared_ptr<const QgsMeshMemoryDataset> o = ds->constDataset( datasetIndex );
 
  235         if ( timesPopulated )
 
  245           mTimes.append( o->time );
 
  249       timesPopulated = 
true;
 
  254   if ( mTimes.isEmpty() )
 
  256     mTimes.push_back( 0.0 );
 
  261     for ( QVector<double>::iterator it = mTimes.begin(); it != mTimes.end(); )
 
  265            ( ( *it >= startTime ) && ( *it <= endTime ) ) )
 
  268         it = mTimes.erase( it );
 
  273   for ( 
const auto &ds : vals )
 
  275     if ( ds->type != mOutputType )
 
  283 bool  QgsMeshCalcUtils::isValid()
 const 
  293 std::shared_ptr<const QgsMeshMemoryDatasetGroup> QgsMeshCalcUtils::group( 
const QString &datasetName )
 const 
  295   return mDatasetGroupMap[datasetName];
 
  298 void QgsMeshCalcUtils::populateSpatialFilter( QgsMeshMemoryDatasetGroup &filter, 
const QgsRectangle &extent )
 const 
  302   filter.clearDatasets();
 
  304   std::shared_ptr<QgsMeshMemoryDataset> output = create( filter );
 
  305   output->time = mTimes[0];
 
  307   const QList<int> faceIndexesForRectangle = triangularMesh()->faceIndexesForRectangle( extent );
 
  308   const QVector<int> trianglesToNativeFaces = triangularMesh()->trianglesToNativeFaces();
 
  312     for ( 
const int faceIndex : faceIndexesForRectangle )
 
  314       const int nativeIndex = trianglesToNativeFaces[faceIndex];
 
  315       const QgsMeshFace face = nativeMesh()->face( nativeIndex );
 
  316       for ( 
const int vertexIndex : face )
 
  318         output->values[vertexIndex].set( D_TRUE );
 
  324     for ( 
const int faceIndex : faceIndexesForRectangle )
 
  326       const int nativeIndex = trianglesToNativeFaces[faceIndex];
 
  327       output->values[nativeIndex].set( D_TRUE );
 
  330   filter.addDataset( output );
 
  334 void QgsMeshCalcUtils::populateMaskFilter( QgsMeshMemoryDatasetGroup &filter, 
const QgsGeometry &mask )
 const 
  338   filter.clearDatasets();
 
  339   std::shared_ptr<QgsMeshMemoryDataset> output = create( filter );
 
  340   output->time = mTimes[0];
 
  342   const QVector<QgsMeshVertex> &vertices = triangularMesh()->vertices();
 
  346     int nativeVertexCount = mMeshLayer->dataProvider()->vertexCount();
 
  348     for ( 
int i = 0; i < nativeVertexCount; ++i )
 
  353         output->values[i].set( D_TRUE );
 
  357         output->values[i].set( D_FALSE );
 
  363     const QVector<QgsMeshFace> &triangles = triangularMesh()->triangles();
 
  364     for ( 
int i = 0; i < triangles.size(); ++i )
 
  371         output->values[i].
set( D_TRUE );
 
  375         output->values[i].set( D_FALSE );
 
  379   filter.addDataset( output );
 
  382 std::shared_ptr<QgsMeshMemoryDataset>  QgsMeshCalcUtils::number( 
double val, 
double time )
 const 
  384   Q_ASSERT( isValid() );
 
  386   std::shared_ptr<QgsMeshMemoryDataset> output = create( mOutputType );
 
  390   if ( std::isnan( val ) )
 
  393       memset( output->active.data(), 0, 
static_cast<size_t>( output->active.size() ) * 
sizeof( 
int ) );
 
  397     for ( 
int i = 0; i < output->values.size(); ++i ) 
 
  399       output->values[i].set( val );
 
  406 void QgsMeshCalcUtils::number( QgsMeshMemoryDatasetGroup &group1, 
double val )
 const 
  408   Q_ASSERT( isValid() );
 
  410   group1.datasets.clear();
 
  411   std::shared_ptr<QgsMeshMemoryDataset> output = number( val, mTimes[0] );
 
  412   group1.datasets.push_back( output );
 
  416 void QgsMeshCalcUtils::ones( QgsMeshMemoryDatasetGroup &group1 )
 const 
  418   Q_ASSERT( isValid() );
 
  419   number( group1, 1.0 );
 
  422 void QgsMeshCalcUtils::nodata( QgsMeshMemoryDatasetGroup &group1 )
 const 
  424   Q_ASSERT( isValid() );
 
  425   number( group1, D_NODATA );
 
  429 std::shared_ptr<QgsMeshMemoryDataset>  QgsMeshCalcUtils::copy(
 
  430   std::shared_ptr<const QgsMeshMemoryDataset> dataset0
 
  433   Q_ASSERT( isValid() );
 
  434   Q_ASSERT( dataset0 );
 
  436   std::shared_ptr<QgsMeshMemoryDataset> output = std::make_shared<QgsMeshMemoryDataset>();
 
  437   output->values = dataset0->values; 
 
  438   output->active = dataset0->active; 
 
  439   output->time = dataset0->time;
 
  440   output->valid = dataset0->valid;
 
  444 void QgsMeshCalcUtils::copy( QgsMeshMemoryDatasetGroup &group1, 
const QString &groupName )
 const 
  446   Q_ASSERT( isValid() );
 
  448   std::shared_ptr<const QgsMeshMemoryDatasetGroup> group2 = group( groupName );
 
  451   if ( group2->datasetCount() == 1 )
 
  454     std::shared_ptr<const QgsMeshMemoryDataset> o0 = group2->constDataset( 0 );
 
  455     std::shared_ptr<QgsMeshMemoryDataset> output = copy( o0 );
 
  456     group1.addDataset( output );
 
  460     for ( 
int output_index = 0; output_index < group2->datasetCount(); ++output_index )
 
  462       std::shared_ptr<const QgsMeshMemoryDataset> o0 = group2->constDataset( output_index );
 
  465            ( ( o0->time >= mTimes.first() ) && ( o0->time <= mTimes.last() ) )
 
  468         std::shared_ptr<QgsMeshMemoryDataset> output = copy( o0 );
 
  469         group1.addDataset( output );
 
  475 void QgsMeshCalcUtils::transferDatasets( QgsMeshMemoryDatasetGroup &group1, QgsMeshMemoryDatasetGroup &group2 )
 const 
  477   Q_ASSERT( isValid() );
 
  479   group1.clearDatasets();
 
  480   for ( 
int i = 0; i < group2.datasetCount(); ++i )
 
  482     std::shared_ptr<QgsMeshMemoryDataset> o = group2.datasets[i];
 
  484     group1.addDataset( o );
 
  486   group2.clearDatasets();
 
  489 void QgsMeshCalcUtils::expand( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
  491   Q_ASSERT( isValid() );
 
  493   if ( group2.datasetCount() > 1 )
 
  495     if ( group1.datasetCount() == 1 )
 
  497       const std::shared_ptr<QgsMeshMemoryDataset> o0 = group1.datasets[0];
 
  499       for ( 
int i = 1; i < group2.datasetCount(); ++i )
 
  501         std::shared_ptr<QgsMeshMemoryDataset> o = copy( o0 );
 
  503         group1.addDataset( o );
 
  510 std::shared_ptr<QgsMeshMemoryDataset>  QgsMeshCalcUtils::canditateDataset(
 
  511   QgsMeshMemoryDatasetGroup &group,
 
  512   int datasetIndex )
 const 
  514   Q_ASSERT( isValid() );
 
  516   if ( group.datasetCount() > 1 )
 
  518     Q_ASSERT( group.datasetCount() > datasetIndex );
 
  519     return group.datasets[datasetIndex];
 
  523     Q_ASSERT( group.datasetCount() == 1 );
 
  524     return group.datasets[0];
 
  528 std::shared_ptr<const QgsMeshMemoryDataset>  QgsMeshCalcUtils::constCandidateDataset(
 
  529   const QgsMeshMemoryDatasetGroup &group,
 
  530   int datasetIndex )
 const 
  532   Q_ASSERT( isValid() );
 
  534   if ( group.datasetCount() > 1 )
 
  536     Q_ASSERT( group.datasetCount() > datasetIndex );
 
  537     return group.constDataset( datasetIndex );
 
  541     Q_ASSERT( group.datasetCount() == 1 );
 
  542     return group.constDataset( 0 );
 
  546 int  QgsMeshCalcUtils::datasetCount(
 
  547   const QgsMeshMemoryDatasetGroup &group1,
 
  548   const QgsMeshMemoryDatasetGroup &group2 )
 const 
  550   Q_ASSERT( isValid() );
 
  552   if ( ( group1.datasetCount() > 1 ) || ( group2.datasetCount() > 1 ) )
 
  554     return mTimes.size();
 
  562 void QgsMeshCalcUtils::func1( QgsMeshMemoryDatasetGroup &group,
 
  563                               std::function<
double( 
double )> func )
 const 
  565   Q_ASSERT( isValid() );
 
  567   for ( 
int time_index = 0; time_index < group.datasetCount(); ++time_index )
 
  569     std::shared_ptr<QgsMeshMemoryDataset> output = canditateDataset( group, time_index );
 
  571     for ( 
int n = 0; n < output->values.size(); ++n )
 
  573       double val1 = output->values[n].scalar();
 
  574       double res_val = D_NODATA;
 
  575       if ( !std::isnan( val1 ) )
 
  576         res_val = func( val1 );
 
  577       output->values[n] = res_val;
 
  586 void QgsMeshCalcUtils::func2( QgsMeshMemoryDatasetGroup &group1,
 
  587                               const QgsMeshMemoryDatasetGroup &group2,
 
  588                               std::function<
double( 
double, 
double )> func )
 const 
  590   Q_ASSERT( isValid() );
 
  591   Q_ASSERT( group1.type == group2.type ); 
 
  593   expand( group1, group2 );
 
  595   for ( 
int time_index = 0; time_index < datasetCount( group1, group2 ); ++time_index )
 
  597     std::shared_ptr<QgsMeshMemoryDataset> o1 = canditateDataset( group1, time_index );
 
  598     std::shared_ptr<const QgsMeshMemoryDataset> o2 = constCandidateDataset( group2, time_index );
 
  600     for ( 
int n = 0; n < o2->values.size(); ++n )
 
  602       double val1 = o1->values[n].scalar();
 
  603       double val2 = o2->values[n].scalar();
 
  604       double res_val = D_NODATA;
 
  605       if ( !std::isnan( val1 ) && !std::isnan( val2 ) )
 
  606         res_val = func( val1, val2 );
 
  607       o1->values[n] = res_val;
 
  618 void QgsMeshCalcUtils::funcAggr(
 
  619   QgsMeshMemoryDatasetGroup &group1,
 
  620   std::function<
double( QVector<double>& )> func
 
  623   Q_ASSERT( isValid() );
 
  628     output->time = mTimes[0];
 
  629     for ( 
int n = 0; n < mMeshLayer->dataProvider()->vertexCount(); ++n )
 
  631       QVector < double > vals;
 
  632       for ( 
int datasetIndex = 0; datasetIndex < group1.datasetCount(); ++datasetIndex )
 
  634         const std::shared_ptr<QgsMeshMemoryDataset> o1 = canditateDataset( group1, datasetIndex );
 
  636         double val1 = o1->values[n].scalar();
 
  640         if ( !std::isnan( val1 ) )
 
  642           vals.push_back( val1 );
 
  646       double res_val = D_NODATA;
 
  647       if ( !vals.isEmpty() )
 
  649         res_val = func( vals );
 
  652       output->values[n] = res_val;
 
  658     group1.datasets.clear();
 
  659     group1.datasets.push_back( output );
 
  665     output->time = mTimes[0];
 
  667     int facesCount = mMeshLayer->dataProvider()->faceCount();
 
  668     output->values.resize( facesCount );
 
  670     for ( 
int n = 0; n < mMeshLayer->dataProvider()->faceCount(); ++n )
 
  672       QVector < double > vals;
 
  673       for ( 
int datasetIndex = 0; datasetIndex < group1.datasetCount(); ++datasetIndex )
 
  675         const std::shared_ptr<QgsMeshMemoryDataset> o1 = canditateDataset( group1, datasetIndex );
 
  676         double val1 = o1->values[n].scalar();
 
  677         if ( !std::isnan( val1 ) )
 
  679           vals.push_back( val1 );
 
  683       double res_val = D_NODATA;
 
  684       if ( !vals.isEmpty() )
 
  686         res_val = func( vals );
 
  689       output->values[n] = res_val;
 
  692     group1.datasets.clear();
 
  693     group1.datasets.push_back( output );
 
  700   Q_ASSERT( mMeshLayer->triangularMesh() );
 
  701   return mMeshLayer->triangularMesh();
 
  704 const QgsMesh *QgsMeshCalcUtils::nativeMesh()
 const 
  707   Q_ASSERT( mMeshLayer->nativeMesh() );
 
  708   return mMeshLayer->nativeMesh();
 
  711 void QgsMeshCalcUtils::updateMesh()
 const 
  713   if ( ! mMeshLayer->nativeMesh() )
 
  716     mMeshLayer->updateTriangularMesh();
 
  725 void QgsMeshCalcUtils::addIf( QgsMeshMemoryDatasetGroup &trueGroup,
 
  726                               const QgsMeshMemoryDatasetGroup &falseGroup,
 
  727                               const QgsMeshMemoryDatasetGroup &condition )
 const 
  729   Q_ASSERT( isValid() );
 
  732   expand( trueGroup, condition );
 
  733   expand( trueGroup, falseGroup );
 
  735   Q_ASSERT( trueGroup.type == falseGroup.type ); 
 
  736   Q_ASSERT( trueGroup.type == condition.type ); 
 
  738   for ( 
int time_index = 0; time_index < trueGroup.datasetCount(); ++time_index )
 
  740     std::shared_ptr<QgsMeshMemoryDataset> true_o = canditateDataset( trueGroup, time_index );
 
  741     std::shared_ptr<const QgsMeshMemoryDataset> false_o = constCandidateDataset( falseGroup, time_index );
 
  742     std::shared_ptr<const QgsMeshMemoryDataset> condition_o = constCandidateDataset( condition, time_index );
 
  743     for ( 
int n = 0; n < true_o->values.size(); ++n )
 
  745       double conditionValue =  condition_o->values[n].scalar();
 
  746       double resultValue = D_NODATA;
 
  747       if ( !std::isnan( conditionValue ) )
 
  750           resultValue = true_o->values[n].scalar();
 
  752           resultValue = false_o->values[n].scalar();
 
  754       true_o->values[n] = resultValue;
 
  761       activate( true_o, condition_o );
 
  767 void QgsMeshCalcUtils::activate( QgsMeshMemoryDatasetGroup &group )
 const 
  769   Q_ASSERT( isValid() );
 
  773     for ( 
int datasetIndex = 0; datasetIndex < group.datasetCount(); ++datasetIndex )
 
  775       std::shared_ptr<QgsMeshMemoryDataset> o1 = canditateDataset( group, datasetIndex );
 
  783 void QgsMeshCalcUtils::activate(
 
  784   std::shared_ptr<QgsMeshMemoryDataset> dataset,
 
  785   std::shared_ptr<const QgsMeshMemoryDataset> refDataset 
 
  789   Q_ASSERT( isValid() );
 
  793   for ( 
int idx = 0; idx < mMeshLayer->dataProvider()->faceCount(); ++idx )
 
  795     if ( refDataset && !refDataset->active.isEmpty() && ( !refDataset->active[idx] ) )
 
  797       dataset->active[idx] = 
false;
 
  801     if ( !dataset->active[idx] )
 
  808     bool isActive = 
true; 
 
  809     for ( 
int j = 0; j < face.size(); ++j )
 
  811       if ( std::isnan( dataset->values[face[j]].scalar() ) )
 
  817     dataset->active[idx] = isActive;
 
  821 double QgsMeshCalcUtils::ffilter( 
double val1, 
double filter )
 const 
  823   Q_ASSERT( !std::isnan( val1 ) );
 
  831 double QgsMeshCalcUtils::fadd( 
double val1, 
double val2 )
 const 
  833   Q_ASSERT( !std::isnan( val1 ) );
 
  834   Q_ASSERT( !std::isnan( val2 ) );
 
  839 double QgsMeshCalcUtils::fsubtract( 
double val1, 
double val2 )
 const 
  841   Q_ASSERT( !std::isnan( val1 ) );
 
  842   Q_ASSERT( !std::isnan( val2 ) );
 
  847 double QgsMeshCalcUtils::fmultiply( 
double val1, 
double val2 )
 const 
  849   Q_ASSERT( !std::isnan( val1 ) );
 
  850   Q_ASSERT( !std::isnan( val2 ) );
 
  855 double QgsMeshCalcUtils::fdivide( 
double val1, 
double val2 )
 const 
  857   Q_ASSERT( !std::isnan( val1 ) );
 
  858   Q_ASSERT( !std::isnan( val2 ) );
 
  866 double QgsMeshCalcUtils::fpower( 
double val1, 
double val2 )
 const 
  868   Q_ASSERT( !std::isnan( val1 ) );
 
  869   Q_ASSERT( !std::isnan( val2 ) );
 
  870   return pow( val1, val2 );
 
  874 double QgsMeshCalcUtils::fequal( 
double val1, 
double val2 )
 const 
  876   Q_ASSERT( !std::isnan( val1 ) );
 
  877   Q_ASSERT( !std::isnan( val2 ) );
 
  889 double QgsMeshCalcUtils::fnotEqual( 
double val1, 
double val2 )
 const 
  891   Q_ASSERT( !std::isnan( val1 ) );
 
  892   Q_ASSERT( !std::isnan( val2 ) );
 
  904 double QgsMeshCalcUtils::fgreaterThan( 
double val1, 
double val2 )
 const 
  906   Q_ASSERT( !std::isnan( val1 ) );
 
  907   Q_ASSERT( !std::isnan( val2 ) );
 
  919 double QgsMeshCalcUtils::flesserThan( 
double val1, 
double val2 )
 const 
  921   Q_ASSERT( !std::isnan( val1 ) );
 
  922   Q_ASSERT( !std::isnan( val2 ) );
 
  934 double QgsMeshCalcUtils::flesserEqual( 
double val1, 
double val2 )
 const 
  936   Q_ASSERT( !std::isnan( val1 ) );
 
  937   Q_ASSERT( !std::isnan( val2 ) );
 
  949 double QgsMeshCalcUtils::fgreaterEqual( 
double val1, 
double val2 )
 const 
  951   Q_ASSERT( !std::isnan( val1 ) );
 
  952   Q_ASSERT( !std::isnan( val2 ) );
 
  965 double QgsMeshCalcUtils::flogicalAnd( 
double val1, 
double val2 )
 const 
  967   Q_ASSERT( !std::isnan( val1 ) );
 
  968   Q_ASSERT( !std::isnan( val2 ) );
 
  971   if ( bval1 && bval2 )
 
  978 double QgsMeshCalcUtils::flogicalOr( 
double val1, 
double val2 )
 const 
  980   Q_ASSERT( !std::isnan( val1 ) );
 
  981   Q_ASSERT( !std::isnan( val2 ) );
 
  984   if ( bval1 || bval2 )
 
  991 double QgsMeshCalcUtils::flogicalNot( 
double val1 )
 const 
  993   Q_ASSERT( !std::isnan( val1 ) );
 
 1002 double QgsMeshCalcUtils::fchangeSign( 
double val1 )
 const 
 1004   Q_ASSERT( !std::isnan( val1 ) );
 
 1008 double QgsMeshCalcUtils::fmin( 
double val1, 
double val2 )
 const 
 1010   Q_ASSERT( !std::isnan( val1 ) );
 
 1022 double QgsMeshCalcUtils::fmax( 
double val1, 
double val2 )
 const 
 1024   Q_ASSERT( !std::isnan( val1 ) );
 
 1025   Q_ASSERT( !std::isnan( val2 ) );
 
 1037 double QgsMeshCalcUtils::fabs( 
double val1 )
 const 
 1039   Q_ASSERT( !std::isnan( val1 ) );
 
 1051 double QgsMeshCalcUtils::fsumAggregated( QVector<double> &vals )
 const 
 1053   Q_ASSERT( !vals.contains( D_NODATA ) );
 
 1054   Q_ASSERT( !vals.isEmpty() );
 
 1055   return std::accumulate( vals.begin(), vals.end(), 0.0 );
 
 1058 double QgsMeshCalcUtils::fminimumAggregated( QVector<double> &vals )
 const 
 1060   Q_ASSERT( !vals.contains( D_NODATA ) );
 
 1061   Q_ASSERT( !vals.isEmpty() );
 
 1062   return *std::min_element( vals.begin(), vals.end() );
 
 1065 double QgsMeshCalcUtils::fmaximumAggregated( QVector<double> &vals )
 const 
 1067   Q_ASSERT( !vals.contains( D_NODATA ) );
 
 1068   Q_ASSERT( !vals.isEmpty() );
 
 1069   return *std::max_element( vals.begin(), vals.end() );
 
 1072 double QgsMeshCalcUtils::faverageAggregated( QVector<double> &vals )
 const 
 1074   Q_ASSERT( !vals.contains( D_NODATA ) );
 
 1075   Q_ASSERT( !vals.isEmpty() );
 
 1076   return fsumAggregated( vals ) / vals.size();
 
 1079 void QgsMeshCalcUtils::logicalNot( QgsMeshMemoryDatasetGroup &group1 )
 const 
 1081   return func1( group1, std::bind( & QgsMeshCalcUtils::flogicalNot, 
this, std::placeholders::_1 ) );
 
 1084 void QgsMeshCalcUtils::changeSign( QgsMeshMemoryDatasetGroup &group1 )
 const 
 1086   return func1( group1, std::bind( & QgsMeshCalcUtils::fchangeSign, 
this, std::placeholders::_1 ) );
 
 1089 void QgsMeshCalcUtils::abs( QgsMeshMemoryDatasetGroup &group1 )
 const 
 1091   return func1( group1, std::bind( & QgsMeshCalcUtils::fabs, 
this, std::placeholders::_1 ) );
 
 1094 void QgsMeshCalcUtils::add( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
 1096   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fadd, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1099 void QgsMeshCalcUtils::subtract( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
 1101   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fsubtract, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1104 void QgsMeshCalcUtils::multiply( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
 1106   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fmultiply, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1109 void QgsMeshCalcUtils::divide( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
 1111   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fdivide, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1114 void QgsMeshCalcUtils::power( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
 1116   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fpower, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1119 void QgsMeshCalcUtils::equal( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
 1121   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fequal, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1124 void QgsMeshCalcUtils::notEqual( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
 1126   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fnotEqual, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1129 void QgsMeshCalcUtils::greaterThan( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
 1131   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fgreaterThan, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1134 void QgsMeshCalcUtils::lesserThan( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
 1136   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::flesserThan, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1139 void QgsMeshCalcUtils::lesserEqual( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
 1141   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::flesserEqual, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1144 void QgsMeshCalcUtils::greaterEqual( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
 1146   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fgreaterEqual, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1149 void QgsMeshCalcUtils::logicalAnd( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
 1151   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::flogicalAnd, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1154 void QgsMeshCalcUtils::logicalOr( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
 1156   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::flogicalOr, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1159 void QgsMeshCalcUtils::minimum( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
 1161   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fmin, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1164 void QgsMeshCalcUtils::maximum( QgsMeshMemoryDatasetGroup &group1, 
const QgsMeshMemoryDatasetGroup &group2 )
 const 
 1166   return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fmax, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1171   QHash<QString, int> names;
 
 1176     const QString name = meta.
name();
 
 1177     names[ name ] = groupId;
 
 1179   for ( 
const auto &datasetGroupName : usedGroupNames )
 
 1181     if ( names.contains( datasetGroupName ) )
 
 1183       int groupId = names.value( datasetGroupName );
 
 1198 void QgsMeshCalcUtils::filter( QgsMeshMemoryDatasetGroup &group1, 
const QgsRectangle &extent )
 const 
 1200   QgsMeshMemoryDatasetGroup filter( 
"filter", outputType() );
 
 1201   populateSpatialFilter( filter, extent );
 
 1202   return func2( group1, filter, std::bind( & QgsMeshCalcUtils::ffilter, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1205 void QgsMeshCalcUtils::filter( QgsMeshMemoryDatasetGroup &group1, 
const QgsGeometry &mask )
 const 
 1207   QgsMeshMemoryDatasetGroup filter( 
"filter", outputType() );
 
 1208   populateMaskFilter( filter, mask );
 
 1209   return func2( group1, filter, std::bind( & QgsMeshCalcUtils::ffilter, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1212 void QgsMeshCalcUtils::sumAggregated( QgsMeshMemoryDatasetGroup &group1 )
 const 
 1214   return funcAggr( group1, std::bind( & QgsMeshCalcUtils::fsumAggregated, 
this, std::placeholders::_1 ) );
 
 1217 void QgsMeshCalcUtils::minimumAggregated( QgsMeshMemoryDatasetGroup &group1 )
 const 
 1219   return funcAggr( group1, std::bind( & QgsMeshCalcUtils::fminimumAggregated, 
this, std::placeholders::_1 ) );
 
 1222 void QgsMeshCalcUtils::maximumAggregated( QgsMeshMemoryDatasetGroup &group1 )
 const 
 1224   return funcAggr( group1, std::bind( & QgsMeshCalcUtils::fmaximumAggregated, 
this, std::placeholders::_1 ) );
 
 1227 void QgsMeshCalcUtils::averageAggregated( QgsMeshMemoryDatasetGroup &group1 )
 const 
 1229   return funcAggr( group1, std::bind( & QgsMeshCalcUtils::faverageAggregated, 
this, std::placeholders::_1 ) );