40    case QgsMeshDatasetGroupMetadata::DataType::DataOnEdges:
 
   42    case QgsMeshDatasetGroupMetadata::DataType::DataOnFaces:
 
   44    case QgsMeshDatasetGroupMetadata::DataType::DataOnVertices:
 
   46    case QgsMeshDatasetGroupMetadata::DataType::DataOnVolumes:
 
   55  if ( type == QgsMeshDatasetGroupMetadata::DataType::DataOnVolumes )
 
   56    return QgsMeshDatasetGroupMetadata::DataType::DataOnFaces;
 
   79  if ( meta.
dataType() != QgsMeshDatasetGroupMetadata::DataType::DataOnVolumes )
 
   88    if ( !averagingMethod )
 
   95    block = averagingMethod->
calculate( block3d );
 
  100QVector<QgsVector> QgsMeshLayerUtils::griddedVectorValues( 
const QgsMeshLayer *meshLayer,
 
  107  QVector<QgsVector> vectors;
 
  109  if ( !meshLayer || !index.
isValid() )
 
  115  if ( !triangularMesh || !nativeMesh )
 
  124  const int datacount = vectorDataOnVertices ? nativeMesh->
vertices.count() : nativeMesh->
faces.count();
 
  125  const QgsMeshDataBlock vals = QgsMeshLayerUtils::datasetValues( meshLayer, index, 0, datacount );
 
  135    vectors.reserve( size.height()*size.width() );
 
  140    return QVector<QgsVector>();
 
  143  for ( 
int iy = 0; iy < size.height(); ++iy )
 
  145    const double y = minCorner.
y() + iy * ySpacing;
 
  146    for ( 
int ix = 0; ix < size.width(); ++ix )
 
  148      const double x = minCorner.
x() + ix * xSpacing;
 
  151      int nativeFaceIndex = -1;
 
  152      if ( faceIndex != -1 )
 
  155      if ( nativeFaceIndex != -1 && isFacesActive.
active( nativeFaceIndex ) )
 
  161            value = vals.
value( nativeFaceIndex );
 
  166            const int v1 = face[0], v2 = face[1], v3 = face[2];
 
  171            const double x = QgsMeshLayerUtils::interpolateFromVerticesData( p1, p2, p3, val1.
x(), val2.
x(), val3.
x(), point );
 
  172            const double y = QgsMeshLayerUtils::interpolateFromVerticesData( p1, p2, p3, val1.
y(), val2.
y(), val3.
y(), point );
 
  180      vectors.append( 
QgsVector( value.
x(), value.
y() ) );
 
  186QVector<double> QgsMeshLayerUtils::calculateMagnitudes( 
const QgsMeshDataBlock &block )
 
  189  const int count = block.
count();
 
  190  QVector<double> ret( count );
 
  192  for ( 
int i = 0; i < count; ++i )
 
  200QgsRectangle QgsMeshLayerUtils::boundingBoxToScreenRectangle(
 
  210  const double xMin = std::min( {topLeft.
x(), topRight.
x(), bottomLeft.
x(), bottomRight.
x()} );
 
  211  const double xMax = std::max( {topLeft.
x(), topRight.
x(), bottomLeft.
x(), bottomRight.
x()} );
 
  212  const double yMin = std::min( {topLeft.
y(), topRight.
y(), bottomLeft.
y(), bottomRight.
y()} );
 
  213  const double yMax = std::max( {topLeft.
y(), topRight.
y(), bottomLeft.
y(), bottomRight.
y()} );
 
  219void QgsMeshLayerUtils::boundingBoxToScreenRectangle(
 
  221  const QSize &outputSize,
 
  228  const QgsRectangle screenBBox = boundingBoxToScreenRectangle( mtp, bbox );
 
  230  bottomLim = std::max( 
int( screenBBox.
yMinimum() ), 0 );
 
  231  topLim = std::min( 
int( screenBBox.
yMaximum() ), outputSize.height() - 1 );
 
  232  leftLim = std::max( 
int( screenBBox.
xMinimum() ), 0 );
 
  233  rightLim = std::min( 
int( screenBBox.
xMaximum() ), outputSize.width() - 1 );
 
  236static void lamTol( 
double &lam )
 
  238  const static double eps = 1e-6;
 
  239  if ( ( lam < 0.0 ) && ( lam > -eps ) )
 
  246                                       double &lam1, 
double &lam2, 
double &lam3 )
 
  249  const double xa = pA.
x();
 
  250  const double ya = pA.
y();
 
  251  const double v0x = pC.
x() - xa ;
 
  252  const double v0y = pC.
y() - ya ;
 
  253  const double v1x = pB.
x() - xa ;
 
  254  const double v1y = pB.
y() - ya ;
 
  255  const double v2x = pP.
x() - xa ;
 
  256  const double v2y = pP.
y() - ya ;
 
  259  const double dot00 = v0x * v0x + v0y * v0y;
 
  260  const double dot01 = v0x * v1x + v0y * v1y;
 
  261  const double dot02 = v0x * v2x + v0y * v2y;
 
  262  const double dot11 = v1x * v1x + v1y * v1y;
 
  263  const double dot12 = v1x * v2x + v1y * v2y;
 
  266  double invDenom =  dot00 * dot11 - dot01 * dot01;
 
  269  invDenom = 1.0 / invDenom;
 
  270  lam1 = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
 
  271  lam2 = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
 
  272  lam3 = 1.0 - lam1 - lam2;
 
  280  if ( ( lam1 < 0 ) || ( lam2 < 0 ) || ( lam3 < 0 ) )
 
  289    double val1, 
double val2, 
double val3, 
const QgsPointXY &pt )
 
  291  double lam1, lam2, lam3;
 
  292  if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
 
  293    return std::numeric_limits<double>::quiet_NaN();
 
  295  return lam1 * val3 + lam2 * val2 + lam3 * val1;
 
  298double QgsMeshLayerUtils::interpolateZForPoint( 
const QgsTriangularMesh &mesh, 
double x, 
double y )
 
  302  if ( faceIndex < 0 || faceIndex >= mesh.
triangles().count() )
 
  303    return std::numeric_limits<float>::quiet_NaN();
 
  311  return QgsMeshLayerUtils::interpolateFromVerticesData( p1, p2, p3, p1.
z(), p2.
z(), p3.
z(), point );
 
  314double QgsMeshLayerUtils::interpolateFromVerticesData( 
double fraction, 
double val1, 
double val2 )
 
  316  if ( std::isnan( val1 ) || std::isnan( val2 ) || ( fraction < 0 ) || ( fraction > 1 ) )
 
  318    return std::numeric_limits<double>::quiet_NaN();
 
  320  return val1 + ( val2 - val1 ) * fraction;
 
  326                              interpolateFromVerticesData( fraction, val1.
y(), val2.
y() ) );
 
  332  double lam1, lam2, lam3;
 
  333  if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
 
  334    return QgsVector( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
 
  336  return vect3 * lam1 + vect2 * lam2 + vect1 * lam3;
 
  342  double lam1, lam2, lam3;
 
  343  if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
 
  344    return std::numeric_limits<double>::quiet_NaN();
 
  352  double lam1, lam2, lam3;
 
  353  if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
 
  354    return QgsVector( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
 
  360QVector<double> QgsMeshLayerUtils::interpolateFromFacesData(
 
  361  QVector<double> valuesOnFaces,
 
  367  assert( nativeMesh );
 
  369  Q_UNUSED( triangularMesh );
 
  374  return interpolateFromFacesData( valuesOnFaces, *nativeMesh, active, method );
 
  377QVector<double> QgsMeshLayerUtils::interpolateFromFacesData( 
const QVector<double> &valuesOnFaces,
 
  385    activeFace = *active;
 
  392  return interpolateFromFacesData( valuesOnFaces, nativeMesh, activeFace, method );
 
  402  QVector<double> res( vertexCount, 0.0 );
 
  404  QVector<int> count( vertexCount, 0 );
 
  406  for ( 
int i = 0; i < nativeMesh.
faceCount(); ++i )
 
  410      const double val = valuesOnFaces[ i ];
 
  411      if ( !std::isnan( val ) )
 
  415        for ( 
int j = 0; j < face.size(); ++j )
 
  417          const int vertexIndex = face[j];
 
  418          res[vertexIndex] += val;
 
  419          count[vertexIndex] += 1;
 
  425  for ( 
int i = 0; i < vertexCount; ++i )
 
  427    if ( count.at( i ) > 0 )
 
  429      res[i] = res[i] / double( count.at( i ) );
 
  433      res[i] = std::numeric_limits<double>::quiet_NaN();
 
  440QVector<double> QgsMeshLayerUtils::resampleFromVerticesToFaces(
 
  441  const QVector<double> valuesOnVertices,
 
  447  assert( nativeMesh );
 
  452  Q_UNUSED( triangularMesh );
 
  455  QVector<double> ret( nativeMesh->
faceCount(), std::numeric_limits<double>::quiet_NaN() );
 
  457  for ( 
int i = 0; i < nativeMesh->
faces.size(); ++i )
 
  460    if ( active->
active( i ) && face.count() > 2 )
 
  463      for ( 
int j = 0; j < face.count(); ++j )
 
  465        value += valuesOnVertices.at( face.at( j ) );
 
  467      ret[i] = value / face.count();
 
  474QVector<double> QgsMeshLayerUtils::calculateMagnitudeOnVertices( 
const QgsMeshLayer *meshLayer,
 
  481  if ( !meshLayer && !index.
isValid() )
 
  486  if ( !triangularMesh || !nativeMesh )
 
  493  const int datacount = scalarDataOnVertices ? nativeMesh->
vertices.count() : nativeMesh->
faces.count();
 
  501  if ( !activeFaceFlagValues )
 
  507    activeFace = *activeFaceFlagValues;
 
  509  return calculateMagnitudeOnVertices( *nativeMesh, metadata, vals, activeFace, method );
 
  512QVector<double> QgsMeshLayerUtils::calculateMagnitudeOnVertices( 
const QgsMesh &nativeMesh,
 
  523    ret = QgsMeshLayerUtils::calculateMagnitudes( datasetValues );
 
  525    if ( !scalarDataOnVertices )
 
  528      ret = QgsMeshLayerUtils::interpolateFromFacesData(
 
  531              activeFaceFlagValues,
 
  541  double xMin = p1.
x();
 
  542  double xMax = p1.
x();
 
  543  double yMin = p1.
y();
 
  544  double yMax = p1.
y();
 
  547  xMin = ( ( xMin < p2.
x() ) ? xMin : p2.
x() );
 
  548  xMax = ( ( xMax > p2.
x() ) ? xMax : p2.
x() );
 
  549  yMin = ( ( yMin < p2.
y() ) ? yMin : p2.
y() );
 
  550  yMax = ( ( yMax > p2.
y() ) ? yMax : p2.
y() );
 
  553  xMin = ( ( xMin < p3.
x() ) ? xMin : p3.
x() );
 
  554  xMax = ( ( xMax > p3.
x() ) ? xMax : p3.
x() );
 
  555  yMin = ( ( yMin < p3.
y() ) ? yMin : p3.
y() );
 
  556  yMax = ( ( yMax > p3.
y() ) ? yMax : p3.
y() );
 
  562QString QgsMeshLayerUtils::formatTime( 
double hours, 
const QDateTime &referenceTime, 
const QgsMeshTimeSettings &settings )
 
  566  if ( referenceTime.isValid() )
 
  569    QDateTime dateTime( referenceTime );
 
  570    const qint64 seconds = 
static_cast<qint64
>( hours * 3600.0 );
 
  571    dateTime = dateTime.addSecs( seconds );
 
  572    ret = dateTime.toString( format );
 
  574      ret = dateTime.toString();
 
  579    format = format.trimmed();
 
  580    const int totalHours = 
static_cast<int>( hours );
 
  582    if ( format == QLatin1String( 
"hh:mm:ss.zzz" ) )
 
  584      const int ms = 
static_cast<int>( hours * 3600.0 * 1000 );
 
  585      const int seconds = ms / 1000;
 
  586      const int z = ms % 1000;
 
  587      int m = seconds / 60;
 
  588      const int s = seconds % 60;
 
  589      const int h = m / 60;
 
  591      ret = QStringLiteral( 
"%1:%2:%3.%4" ).
 
  592            arg( h, 2, 10, QLatin1Char( 
'0' ) ).
 
  593            arg( m, 2, 10, QLatin1Char( 
'0' ) ).
 
  594            arg( s, 2, 10, QLatin1Char( 
'0' ) ).
 
  595            arg( z, 3, 10, QLatin1Char( 
'0' ) );
 
  597    else if ( format == QLatin1String( 
"hh:mm:ss" ) )
 
  599      const int seconds = 
static_cast<int>( hours * 3600.0 );
 
  600      int m = seconds / 60;
 
  601      const int s = seconds % 60;
 
  602      const int h = m / 60;
 
  604      ret = QStringLiteral( 
"%1:%2:%3" ).
 
  605            arg( h, 2, 10, QLatin1Char( 
'0' ) ).
 
  606            arg( m, 2, 10, QLatin1Char( 
'0' ) ).
 
  607            arg( s, 2, 10, QLatin1Char( 
'0' ) );
 
  610    else if ( format == QLatin1String( 
"d hh:mm:ss" ) )
 
  612      const int seconds = 
static_cast<int>( hours * 3600.0 );
 
  613      int m = seconds / 60;
 
  614      const int s = seconds % 60;
 
  617      const int d = totalHours / 24;
 
  619      ret = QStringLiteral( 
"%1 d %2:%3:%4" ).
 
  621            arg( h, 2, 10, QLatin1Char( 
'0' ) ).
 
  622            arg( m, 2, 10, QLatin1Char( 
'0' ) ).
 
  623            arg( s, 2, 10, QLatin1Char( 
'0' ) );
 
  625    else if ( format == QLatin1String( 
"d hh" ) )
 
  627      const int d = totalHours / 24;
 
  628      const int h = totalHours % 24;
 
  629      ret = QStringLiteral( 
"%1 d %2" ).
 
  633    else if ( format == QLatin1String( 
"d" ) )
 
  635      const int d = totalHours / 24;
 
  636      ret = QString::number( d );
 
  638    else if ( format == QLatin1String( 
"ss" ) )
 
  640      const int seconds = 
static_cast<int>( hours * 3600.0 );
 
  641      ret = QString::number( seconds );
 
  645      ret = QString::number( hours );
 
  651QVector<QVector3D> QgsMeshLayerUtils::calculateNormals( 
const QgsTriangularMesh &triangularMesh, 
const QVector<double> &verticalMagnitude, 
bool isRelative )
 
  653  QVector<QVector3D> normals( triangularMesh.
vertices().count() );
 
  654  for ( 
const auto &face : triangularMesh.
triangles() )
 
  656    for ( 
int i = 0; i < 3; i++ )
 
  658      const int index( face.at( i ) );
 
  659      const int index1( face.at( ( i + 1 ) % 3 ) );
 
  660      const int index2( face.at( ( i + 2 ) % 3 ) );
 
  662      if ( std::isnan( verticalMagnitude[index] ) ||
 
  663           std::isnan( verticalMagnitude[index1] ) ||
 
  664           std::isnan( verticalMagnitude[index2] ) )
 
  671      float adjustRelative = 0;
 
  672      float adjustRelative1 = 0;
 
  673      float adjustRelative2 = 0;
 
  677        adjustRelative = vert.z();
 
  678        adjustRelative1 = otherVert1.z();
 
  679        adjustRelative2 = otherVert2.z();
 
  682      const QVector3D v1( 
float( otherVert1.x() - vert.x() ),
 
  683                          float( otherVert1.y() - vert.y() ),
 
  684                          float( verticalMagnitude[index1] - verticalMagnitude[index] + adjustRelative1 - adjustRelative ) );
 
  685      const QVector3D v2( 
float( otherVert2.x() - vert.x() ),
 
  686                          float( otherVert2.y() - vert.y() ),
 
  687                          float( verticalMagnitude[index2] - verticalMagnitude[index] + adjustRelative2 - adjustRelative ) );
 
  689      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.
 
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.
 
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).
 
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 yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
 
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
 
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
 
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom 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.