21#include <QRegularExpression> 
   22#include <QRegularExpressionMatch> 
   90    if ( !averagingMethod )
 
   97    block = averagingMethod->
calculate( block3d );
 
  102QVector<QgsVector> QgsMeshLayerUtils::griddedVectorValues( 
const QgsMeshLayer *meshLayer,
 
  109  QVector<QgsVector> vectors;
 
  111  if ( !meshLayer || !index.
isValid() )
 
  117  if ( !triangularMesh || !nativeMesh )
 
  126  const int datacount = vectorDataOnVertices ? nativeMesh->
vertices.count() : nativeMesh->
faces.count();
 
  127  const QgsMeshDataBlock vals = QgsMeshLayerUtils::datasetValues( meshLayer, index, 0, datacount );
 
  137    vectors.reserve( size.height()*size.width() );
 
  142    return QVector<QgsVector>();
 
  145  for ( 
int iy = 0; iy < size.height(); ++iy )
 
  147    const double y = minCorner.
y() + iy * ySpacing;
 
  148    for ( 
int ix = 0; ix < size.width(); ++ix )
 
  150      const double x = minCorner.
x() + ix * xSpacing;
 
  153      int nativeFaceIndex = -1;
 
  154      if ( faceIndex != -1 )
 
  157      if ( nativeFaceIndex != -1 && isFacesActive.
active( nativeFaceIndex ) )
 
  163            value = vals.
value( nativeFaceIndex );
 
  168            const int v1 = face[0], v2 = face[1], v3 = face[2];
 
  173            const double x = QgsMeshLayerUtils::interpolateFromVerticesData( p1, p2, p3, val1.
x(), val2.
x(), val3.
x(), point );
 
  174            const double y = QgsMeshLayerUtils::interpolateFromVerticesData( p1, p2, p3, val1.
y(), val2.
y(), val3.
y(), point );
 
  182      vectors.append( 
QgsVector( value.
x(), value.
y() ) );
 
  188QVector<double> QgsMeshLayerUtils::calculateMagnitudes( 
const QgsMeshDataBlock &block )
 
  191  const int count = block.
count();
 
  192  QVector<double> ret( count );
 
  194  for ( 
int i = 0; i < count; ++i )
 
  202QgsRectangle QgsMeshLayerUtils::boundingBoxToScreenRectangle(
 
  205  double devicePixelRatio
 
  213  const double xMin = std::min( {topLeft.
x(), topRight.
x(), bottomLeft.
x(), bottomRight.
x()} );
 
  214  const double xMax = std::max( {topLeft.
x(), topRight.
x(), bottomLeft.
x(), bottomRight.
x()} );
 
  215  const double yMin = std::min( {topLeft.
y(), topRight.
y(), bottomLeft.
y(), bottomRight.
y()} );
 
  216  const double yMax = std::max( {topLeft.
y(), topRight.
y(), bottomLeft.
y(), bottomRight.
y()} );
 
  222void QgsMeshLayerUtils::boundingBoxToScreenRectangle(
 
  224  const QSize &outputSize,
 
  230  double devicePixelRatio )
 
  232  const QgsRectangle screenBBox = boundingBoxToScreenRectangle( mtp, bbox, devicePixelRatio );
 
  234  bottomLim = std::max( 
int( screenBBox.
yMinimum() ), 0 );
 
  235  topLim = std::min( 
int( screenBBox.
yMaximum() ), outputSize.height() - 1 );
 
  236  leftLim = std::max( 
int( screenBBox.
xMinimum() ), 0 );
 
  237  rightLim = std::min( 
int( screenBBox.
xMaximum() ), outputSize.width() - 1 );
 
  240static void lamTol( 
double &lam )
 
  242  const static double eps = 1e-6;
 
  243  if ( ( lam < 0.0 ) && ( lam > -eps ) )
 
  250                                       double &lam1, 
double &lam2, 
double &lam3 )
 
  253  const double xa = pA.
x();
 
  254  const double ya = pA.
y();
 
  255  const double v0x = pC.
x() - xa ;
 
  256  const double v0y = pC.
y() - ya ;
 
  257  const double v1x = pB.
x() - xa ;
 
  258  const double v1y = pB.
y() - ya ;
 
  259  const double v2x = pP.
x() - xa ;
 
  260  const double v2y = pP.
y() - ya ;
 
  263  const double dot00 = v0x * v0x + v0y * v0y;
 
  264  const double dot01 = v0x * v1x + v0y * v1y;
 
  265  const double dot02 = v0x * v2x + v0y * v2y;
 
  266  const double dot11 = v1x * v1x + v1y * v1y;
 
  267  const double dot12 = v1x * v2x + v1y * v2y;
 
  270  double invDenom =  dot00 * dot11 - dot01 * dot01;
 
  273  invDenom = 1.0 / invDenom;
 
  274  lam1 = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
 
  275  lam2 = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
 
  276  lam3 = 1.0 - lam1 - lam2;
 
  284  if ( ( lam1 < 0 ) || ( lam2 < 0 ) || ( lam3 < 0 ) )
 
  292bool QgsMeshLayerUtils::calculateBarycentricCoordinates(
 
  294  double &lam1, 
double &lam2, 
double &lam3 )
 
  296  return E3T_physicalToBarycentric( pA, pB, pC, pP, lam1, lam2, lam3 );
 
  300    double val1, 
double val2, 
double val3, 
const QgsPointXY &pt )
 
  302  double lam1, lam2, lam3;
 
  303  if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
 
  304    return std::numeric_limits<double>::quiet_NaN();
 
  306  return lam1 * val3 + lam2 * val2 + lam3 * val1;
 
  309double QgsMeshLayerUtils::interpolateZForPoint( 
const QgsTriangularMesh &mesh, 
double x, 
double y )
 
  313  if ( faceIndex < 0 || faceIndex >= mesh.
triangles().count() )
 
  314    return std::numeric_limits<float>::quiet_NaN();
 
  322  return QgsMeshLayerUtils::interpolateFromVerticesData( p1, p2, p3, p1.
z(), p2.
z(), p3.
z(), point );
 
  325double QgsMeshLayerUtils::interpolateFromVerticesData( 
double fraction, 
double val1, 
double val2 )
 
  327  if ( std::isnan( val1 ) || std::isnan( val2 ) || ( fraction < 0 ) || ( fraction > 1 ) )
 
  329    return std::numeric_limits<double>::quiet_NaN();
 
  331  return val1 + ( val2 - val1 ) * fraction;
 
  337                              interpolateFromVerticesData( fraction, val1.
y(), val2.
y() ) );
 
  343  double lam1, lam2, lam3;
 
  344  if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
 
  345    return QgsVector( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
 
  347  return vect3 * lam1 + vect2 * lam2 + vect1 * lam3;
 
  353  double lam1, lam2, lam3;
 
  354  if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
 
  355    return std::numeric_limits<double>::quiet_NaN();
 
  363  double lam1, lam2, lam3;
 
  364  if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
 
  365    return QgsVector( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
 
  371QVector<double> QgsMeshLayerUtils::interpolateFromFacesData(
 
  372  QVector<double> valuesOnFaces,
 
  378  assert( nativeMesh );
 
  380  Q_UNUSED( triangularMesh );
 
  385  return interpolateFromFacesData( valuesOnFaces, *nativeMesh, active, method );
 
  388QVector<double> QgsMeshLayerUtils::interpolateFromFacesData( 
const QVector<double> &valuesOnFaces,
 
  396    activeFace = *active;
 
  403  return interpolateFromFacesData( valuesOnFaces, nativeMesh, activeFace, method );
 
  413  QVector<double> res( vertexCount, 0.0 );
 
  415  QVector<int> count( vertexCount, 0 );
 
  417  for ( 
int i = 0; i < nativeMesh.
faceCount(); ++i )
 
  421      const double val = valuesOnFaces[ i ];
 
  422      if ( !std::isnan( val ) )
 
  426        for ( 
int j = 0; j < face.size(); ++j )
 
  428          const int vertexIndex = face[j];
 
  429          res[vertexIndex] += val;
 
  430          count[vertexIndex] += 1;
 
  436  for ( 
int i = 0; i < vertexCount; ++i )
 
  438    if ( count.at( i ) > 0 )
 
  440      res[i] = res[i] / double( count.at( i ) );
 
  444      res[i] = std::numeric_limits<double>::quiet_NaN();
 
  451QVector<double> QgsMeshLayerUtils::resampleFromVerticesToFaces(
 
  452  const QVector<double> valuesOnVertices,
 
  458  assert( nativeMesh );
 
  463  Q_UNUSED( triangularMesh );
 
  466  QVector<double> ret( nativeMesh->
faceCount(), std::numeric_limits<double>::quiet_NaN() );
 
  468  for ( 
int i = 0; i < nativeMesh->
faces.size(); ++i )
 
  471    if ( active->
active( i ) && face.count() > 2 )
 
  474      for ( 
int j = 0; j < face.count(); ++j )
 
  476        value += valuesOnVertices.at( face.at( j ) );
 
  478      ret[i] = value / face.count();
 
  485QVector<double> QgsMeshLayerUtils::calculateMagnitudeOnVertices( 
const QgsMeshLayer *meshLayer,
 
  492  if ( !meshLayer && !index.
isValid() )
 
  497  if ( !triangularMesh || !nativeMesh )
 
  504  const int datacount = scalarDataOnVertices ? nativeMesh->
vertices.count() : nativeMesh->
faces.count();
 
  512  if ( !activeFaceFlagValues )
 
  518    activeFace = *activeFaceFlagValues;
 
  520  return calculateMagnitudeOnVertices( *nativeMesh, metadata, vals, activeFace, method );
 
  523QVector<double> QgsMeshLayerUtils::calculateMagnitudeOnVertices( 
const QgsMesh &nativeMesh,
 
  534    ret = QgsMeshLayerUtils::calculateMagnitudes( datasetValues );
 
  536    if ( !scalarDataOnVertices )
 
  539      ret = QgsMeshLayerUtils::interpolateFromFacesData(
 
  542              activeFaceFlagValues,
 
  552  double xMin = p1.
x();
 
  553  double xMax = p1.
x();
 
  554  double yMin = p1.
y();
 
  555  double yMax = p1.
y();
 
  558  xMin = ( ( xMin < p2.
x() ) ? xMin : p2.x() );
 
  559  xMax = ( ( xMax > p2.
x() ) ? xMax : p2.x() );
 
  560  yMin = ( ( yMin < p2.
y() ) ? yMin : p2.y() );
 
  561  yMax = ( ( yMax > p2.
y() ) ? yMax : p2.y() );
 
  564  xMin = ( ( xMin < p3.
x() ) ? xMin : p3.x() );
 
  565  xMax = ( ( xMax > p3.
x() ) ? xMax : p3.x() );
 
  566  yMin = ( ( yMin < p3.
y() ) ? yMin : p3.y() );
 
  567  yMax = ( ( yMax > p3.
y() ) ? yMax : p3.y() );
 
  573QString QgsMeshLayerUtils::formatTime( 
double hours, 
const QDateTime &referenceTime, 
const QgsMeshTimeSettings &settings )
 
  577  if ( referenceTime.isValid() )
 
  580    QDateTime dateTime( referenceTime );
 
  581    const qint64 seconds = 
static_cast<qint64
>( hours * 3600.0 );
 
  582    dateTime = dateTime.addSecs( seconds );
 
  583    ret = dateTime.toString( format );
 
  585      ret = dateTime.toString();
 
  590    format = format.trimmed();
 
  591    const int totalHours = 
static_cast<int>( hours );
 
  593    if ( format == QLatin1String( 
"hh:mm:ss.zzz" ) )
 
  595      const int ms = 
static_cast<int>( hours * 3600.0 * 1000 );
 
  596      const int seconds = ms / 1000;
 
  597      const int z = ms % 1000;
 
  598      int m = seconds / 60;
 
  599      const int s = seconds % 60;
 
  600      const int h = m / 60;
 
  602      ret = QStringLiteral( 
"%1:%2:%3.%4" ).
 
  603            arg( h, 2, 10, QLatin1Char( 
'0' ) ).
 
  604            arg( m, 2, 10, QLatin1Char( 
'0' ) ).
 
  605            arg( s, 2, 10, QLatin1Char( 
'0' ) ).
 
  606            arg( z, 3, 10, QLatin1Char( 
'0' ) );
 
  608    else if ( format == QLatin1String( 
"hh:mm:ss" ) )
 
  610      const int seconds = 
static_cast<int>( hours * 3600.0 );
 
  611      int m = seconds / 60;
 
  612      const int s = seconds % 60;
 
  613      const int h = m / 60;
 
  615      ret = QStringLiteral( 
"%1:%2:%3" ).
 
  616            arg( h, 2, 10, QLatin1Char( 
'0' ) ).
 
  617            arg( m, 2, 10, QLatin1Char( 
'0' ) ).
 
  618            arg( s, 2, 10, QLatin1Char( 
'0' ) );
 
  621    else if ( format == QLatin1String( 
"d hh:mm:ss" ) )
 
  623      const int seconds = 
static_cast<int>( hours * 3600.0 );
 
  624      int m = seconds / 60;
 
  625      const int s = seconds % 60;
 
  628      const int d = totalHours / 24;
 
  630      ret = QStringLiteral( 
"%1 d %2:%3:%4" ).
 
  632            arg( h, 2, 10, QLatin1Char( 
'0' ) ).
 
  633            arg( m, 2, 10, QLatin1Char( 
'0' ) ).
 
  634            arg( s, 2, 10, QLatin1Char( 
'0' ) );
 
  636    else if ( format == QLatin1String( 
"d hh" ) )
 
  638      const int d = totalHours / 24;
 
  639      const int h = totalHours % 24;
 
  640      ret = QStringLiteral( 
"%1 d %2" ).
 
  644    else if ( format == QLatin1String( 
"d" ) )
 
  646      const int d = totalHours / 24;
 
  647      ret = QString::number( d );
 
  649    else if ( format == QLatin1String( 
"ss" ) )
 
  651      const int seconds = 
static_cast<int>( hours * 3600.0 );
 
  652      ret = QString::number( seconds );
 
  656      ret = QString::number( hours );
 
  662QVector<QVector3D> QgsMeshLayerUtils::calculateNormals( 
const QgsTriangularMesh &triangularMesh, 
const QVector<double> &verticalMagnitude, 
bool isRelative )
 
  664  QVector<QVector3D> normals( triangularMesh.
vertices().count() );
 
  665  for ( 
const auto &face : triangularMesh.triangles() )
 
  667    for ( 
int i = 0; i < 3; i++ )
 
  669      const int index( face.at( i ) );
 
  670      const int index1( face.at( ( i + 1 ) % 3 ) );
 
  671      const int index2( face.at( ( i + 2 ) % 3 ) );
 
  673      if ( std::isnan( verticalMagnitude[index] ) ||
 
  674           std::isnan( verticalMagnitude[index1] ) ||
 
  675           std::isnan( verticalMagnitude[index2] ) )
 
  682      float adjustRelative = 0;
 
  683      float adjustRelative1 = 0;
 
  684      float adjustRelative2 = 0;
 
  688        adjustRelative = vert.z();
 
  689        adjustRelative1 = otherVert1.z();
 
  690        adjustRelative2 = otherVert2.z();
 
  693      const QVector3D v1( 
float( otherVert1.x() - vert.x() ),
 
  694                          float( otherVert1.y() - vert.y() ),
 
  695                          float( verticalMagnitude[index1] - verticalMagnitude[index] + adjustRelative1 - adjustRelative ) );
 
  696      const QVector3D v2( 
float( otherVert2.x() - vert.x() ),
 
  697                          float( otherVert2.y() - vert.y() ),
 
  698                          float( verticalMagnitude[index2] - verticalMagnitude[index] + adjustRelative2 - adjustRelative ) );
 
  700      normals[index] += QVector3D::crossProduct( v1, v2 );
 
Perform transforms between map coordinates and device coordinates.
 
QgsPointXY transform(const QgsPointXY &p) const
Transforms a point p from map (world) coordinates to device coordinates.
 
Abstract class to interpolate 3d stacked mesh data to 2d data.
 
QgsMeshDataBlock calculate(const QgsMesh3DDataBlock &block3d, QgsFeedback *feedback=nullptr) const
Calculated 2d block values from 3d stacked mesh values.
 
QgsMesh3DDataBlock is a block of 3d stacked mesh data related N faces defined on base mesh frame.
 
bool isValid() const
Whether the block is valid.
 
QgsMeshDataBlock is a block of integers/doubles that can be used to retrieve: active flags (e....
 
QgsMeshDatasetValue value(int index) const
Returns a value represented by the index For active flag the behavior is undefined.
 
bool isValid() const
Whether the block is valid.
 
DataType type() const
Type of data stored in the block.
 
@ ActiveFlagInteger
Integer boolean flag whether face is active.
 
bool active(int index) const
Returns a value for active flag by the index For scalar and vector 2d the behavior is undefined.
 
int count() const
Number of items stored in the block.
 
void setValid(bool valid)
Sets block validity.
 
QgsMeshDatasetIndex is index that identifies the dataset group (e.g.
 
bool isValid() const
Returns whether index is valid, ie at least groups is set.
 
int group() const
Returns a group index.
 
QgsMeshDatasetValue represents single dataset value.
 
double y() const
Returns y value.
 
double scalar() const
Returns magnitude of vector for vector data or scalar value for scalar data.
 
double x() const
Returns x value.
 
Represents a mesh layer supporting display of data on structured or unstructured meshes.
 
int datasetCount(const QgsMeshDatasetIndex &index) const
Returns the dataset count in the dataset groups.
 
QgsMeshRendererSettings rendererSettings() const
Returns renderer settings.
 
QgsMesh * nativeMesh()
Returns native mesh (nullptr before rendering or calling to updateMesh)
 
QgsMeshDataBlock datasetValues(const QgsMeshDatasetIndex &index, int valueIndex, int count) const
Returns N vector/scalar values from the index from the dataset.
 
QgsMeshDataBlock areFacesActive(const QgsMeshDatasetIndex &index, int faceIndex, int count) const
Returns whether the faces are active for particular dataset.
 
QgsTriangularMesh * triangularMesh(double minimumTriangleSize=0) const
Returns triangular mesh (nullptr before rendering or calling to updateMesh).
 
QgsMesh3DDataBlock dataset3dValues(const QgsMeshDatasetIndex &index, int faceIndex, int count) const
Returns N vector/scalar values from the face index from the dataset for 3d stacked meshes.
 
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
 
DataResamplingMethod
Resampling of value from dataset.
 
@ NeighbourAverage
Does a simple average of values defined for all surrounding faces/vertices.
 
QgsMesh3DAveragingMethod * averagingMethod() const
Returns averaging method for conversion of 3d stacked mesh data to 2d data.
 
Represents a mesh time settings for mesh datasets.
 
QString relativeTimeFormat() const
Returns format used for relative time.
 
QString absoluteTimeFormat() const
Returns format used for absolute time.
 
A class to represent a 2D point.
 
Point geometry type, with support for z-dimension and m-values.
 
A rectangle specified with double values.
 
double xMinimum() const
Returns the x minimum value (left side of rectangle).
 
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
 
double xMaximum() const
Returns the x maximum value (right side of rectangle).
 
double yMaximum() const
Returns the y maximum value (top side of rectangle).
 
Triangular/Derived Mesh is mesh with vertices in map coordinates.
 
const QVector< QgsMeshFace > & triangles() const
Returns triangles.
 
const QVector< QgsMeshVertex > & vertices() const
Returns vertices in map coordinate system.
 
const QVector< int > & trianglesToNativeFaces() const
Returns mapping between triangles and original faces.
 
int faceIndexForPoint_v2(const QgsPointXY &point) const
Finds index of triangle at given point It uses spatial indexing and don't use geos to be faster.
 
A class to represent a vector.
 
#define QgsDebugMsgLevel(str, level)
 
QVector< int > QgsMeshFace
List of vertex indexes.
 
Mesh - vertices, edges and faces.
 
int vertexCount() const
Returns number of vertices.
 
QVector< QgsMeshVertex > vertices
 
QgsMeshFace face(int index) const
Returns a face at the index.
 
QVector< QgsMeshFace > faces
 
int faceCount() const
Returns number of faces.
 
int edgeCount() const
Returns number of edge.