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 );
 
  100 QVector<QgsVector> QgsMeshLayerUtils::griddedVectorValues( 
const QgsMeshLayer *meshLayer,
 
  107   QVector<QgsVector> vectors;
 
  109   if ( !meshLayer || !index.
isValid() )
 
  115   if ( !triangularMesh || !nativeMesh )
 
  124   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     double y = minCorner.
y() + iy * ySpacing;
 
  146     for ( 
int ix = 0; ix < size.width(); ++ix )
 
  148       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() ) );
 
  186 QVector<double> QgsMeshLayerUtils::calculateMagnitudes( 
const QgsMeshDataBlock &block )
 
  189   int count = block.
count();
 
  190   QVector<double> ret( count );
 
  192   for ( 
int i = 0; i < count; ++i )
 
  200 QgsRectangle QgsMeshLayerUtils::boundingBoxToScreenRectangle(
 
  210   double xMin = std::min( {topLeft.
x(), topRight.
x(), bottomLeft.
x(), bottomRight.
x()} );
 
  211   double xMax = std::max( {topLeft.
x(), topRight.
x(), bottomLeft.
x(), bottomRight.
x()} );
 
  212   double yMin = std::min( {topLeft.
y(), topRight.
y(), bottomLeft.
y(), bottomRight.
y()} );
 
  213   double yMax = std::max( {topLeft.
y(), topRight.
y(), bottomLeft.
y(), bottomRight.
y()} );
 
  219 void 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 );
 
  236 static 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 )
 
  251   double v0x = pC.
x() - xa ;
 
  252   double v0y = pC.
y() - ya ;
 
  253   double v1x = pB.
x() - xa ;
 
  254   double v1y = pB.
y() - ya ;
 
  255   double v2x = pP.
x() - xa ;
 
  256   double v2y = pP.
y() - ya ;
 
  259   double dot00 = v0x * v0x + v0y * v0y;
 
  260   double dot01 = v0x * v1x + v0y * v1y;
 
  261   double dot02 = v0x * v2x + v0y * v2y;
 
  262   double dot11 = v1x * v1x + v1y * v1y;
 
  263   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;
 
  298 double QgsMeshLayerUtils::interpolateFromVerticesData( 
double fraction, 
double val1, 
double val2 )
 
  300   if ( std::isnan( val1 ) || std::isnan( val2 ) || ( fraction < 0 ) || ( fraction > 1 ) )
 
  302     return std::numeric_limits<double>::quiet_NaN();
 
  304   return val1 + ( val2 - val1 ) * fraction;
 
  310                               interpolateFromVerticesData( fraction, val1.
y(), val2.
y() ) );
 
  316   double lam1, lam2, lam3;
 
  317   if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
 
  318     return QgsVector( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
 
  320   return vect3 * lam1 + vect2 * lam2 + vect1 * lam3;
 
  326   double lam1, lam2, lam3;
 
  327   if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
 
  328     return std::numeric_limits<double>::quiet_NaN();
 
  336   double lam1, lam2, lam3;
 
  337   if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
 
  338     return QgsVector( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
 
  344 QVector<double> QgsMeshLayerUtils::interpolateFromFacesData(
 
  345   QVector<double> valuesOnFaces,
 
  351   assert( nativeMesh );
 
  353   Q_UNUSED( triangularMesh );
 
  358   return interpolateFromFacesData( valuesOnFaces, *nativeMesh, active, method );
 
  361 QVector<double> QgsMeshLayerUtils::interpolateFromFacesData( 
const QVector<double> &valuesOnFaces,
 
  369     activeFace = *active;
 
  376   return interpolateFromFacesData( valuesOnFaces, nativeMesh, activeFace, method );
 
  386   QVector<double> res( vertexCount, 0.0 );
 
  388   QVector<int> count( vertexCount, 0 );
 
  390   for ( 
int i = 0; i < nativeMesh.
faceCount(); ++i )
 
  394       double val = valuesOnFaces[ i ];
 
  395       if ( !std::isnan( val ) )
 
  399         for ( 
int j = 0; j < face.size(); ++j )
 
  401           int vertexIndex = face[j];
 
  402           res[vertexIndex] += val;
 
  403           count[vertexIndex] += 1;
 
  409   for ( 
int i = 0; i < vertexCount; ++i )
 
  411     if ( count.at( i ) > 0 )
 
  413       res[i] = res[i] / double( count.at( i ) );
 
  417       res[i] = std::numeric_limits<double>::quiet_NaN();
 
  424 QVector<double> QgsMeshLayerUtils::resampleFromVerticesToFaces(
 
  425   const QVector<double> valuesOnVertices,
 
  431   assert( nativeMesh );
 
  436   Q_UNUSED( triangularMesh );
 
  439   QVector<double> ret( nativeMesh->
faceCount(), std::numeric_limits<double>::quiet_NaN() );
 
  441   for ( 
int i = 0; i < nativeMesh->
faces.size(); ++i )
 
  444     if ( active->
active( i ) && face.count() > 2 )
 
  447       for ( 
int j = 0; j < face.count(); ++j )
 
  449         value += valuesOnVertices.at( face.at( j ) );
 
  451       ret[i] = value / face.count();
 
  458 QVector<double> QgsMeshLayerUtils::calculateMagnitudeOnVertices( 
const QgsMeshLayer *meshLayer,
 
  465   if ( !meshLayer && !index.
isValid() )
 
  470   if ( !triangularMesh || !nativeMesh )
 
  477   int datacount = scalarDataOnVertices ? nativeMesh->
vertices.count() : nativeMesh->
faces.count();
 
  485   if ( !activeFaceFlagValues )
 
  491     activeFace = *activeFaceFlagValues;
 
  493   return calculateMagnitudeOnVertices( *nativeMesh, metadata, vals, activeFace, method );
 
  496 QVector<double> QgsMeshLayerUtils::calculateMagnitudeOnVertices( 
const QgsMesh &nativeMesh,
 
  507     ret = QgsMeshLayerUtils::calculateMagnitudes( datasetValues );
 
  509     if ( !scalarDataOnVertices )
 
  512       ret = QgsMeshLayerUtils::interpolateFromFacesData(
 
  515               activeFaceFlagValues,
 
  525   double xMin = p1.
x();
 
  526   double xMax = p1.
x();
 
  527   double yMin = p1.
y();
 
  528   double yMax = p1.
y();
 
  531   xMin = ( ( xMin < p2.
x() ) ? xMin : p2.
x() );
 
  532   xMax = ( ( xMax > p2.
x() ) ? xMax : p2.
x() );
 
  533   yMin = ( ( yMin < p2.
y() ) ? yMin : p2.
y() );
 
  534   yMax = ( ( yMax > p2.
y() ) ? yMax : p2.
y() );
 
  537   xMin = ( ( xMin < p3.
x() ) ? xMin : p3.
x() );
 
  538   xMax = ( ( xMax > p3.
x() ) ? xMax : p3.
x() );
 
  539   yMin = ( ( yMin < p3.
y() ) ? yMin : p3.
y() );
 
  540   yMax = ( ( yMax > p3.
y() ) ? yMax : p3.
y() );
 
  546 QString QgsMeshLayerUtils::formatTime( 
double hours, 
const QDateTime &referenceTime, 
const QgsMeshTimeSettings &settings )
 
  550   if ( referenceTime.isValid() )
 
  553     QDateTime dateTime( referenceTime );
 
  554     qint64 seconds = 
static_cast<qint64
>( hours * 3600.0 );
 
  555     dateTime = dateTime.addSecs( seconds );
 
  556     ret = dateTime.toString( format );
 
  558       ret = dateTime.toString();
 
  563     format = format.trimmed();
 
  564     int totalHours = 
static_cast<int>( hours );
 
  566     if ( format == QLatin1String( 
"hh:mm:ss.zzz" ) )
 
  568       int ms = 
static_cast<int>( hours * 3600.0 * 1000 );
 
  569       int seconds = ms / 1000;
 
  571       int m = seconds / 60;
 
  572       int s = seconds % 60;
 
  575       ret = QStringLiteral( 
"%1:%2:%3.%4" ).
 
  576             arg( h, 2, 10, QLatin1Char( 
'0' ) ).
 
  577             arg( m, 2, 10, QLatin1Char( 
'0' ) ).
 
  578             arg( s, 2, 10, QLatin1Char( 
'0' ) ).
 
  579             arg( z, 3, 10, QLatin1Char( 
'0' ) );
 
  581     else if ( format == QLatin1String( 
"hh:mm:ss" ) )
 
  583       int seconds = 
static_cast<int>( hours * 3600.0 );
 
  584       int m = seconds / 60;
 
  585       int s = seconds % 60;
 
  588       ret = QStringLiteral( 
"%1:%2:%3" ).
 
  589             arg( h, 2, 10, QLatin1Char( 
'0' ) ).
 
  590             arg( m, 2, 10, QLatin1Char( 
'0' ) ).
 
  591             arg( s, 2, 10, QLatin1Char( 
'0' ) );
 
  594     else if ( format == QLatin1String( 
"d hh:mm:ss" ) )
 
  596       int seconds = 
static_cast<int>( hours * 3600.0 );
 
  597       int m = seconds / 60;
 
  598       int s = seconds % 60;
 
  601       int d = totalHours / 24;
 
  603       ret = QStringLiteral( 
"%1 d %2:%3:%4" ).
 
  605             arg( h, 2, 10, QLatin1Char( 
'0' ) ).
 
  606             arg( m, 2, 10, QLatin1Char( 
'0' ) ).
 
  607             arg( s, 2, 10, QLatin1Char( 
'0' ) );
 
  609     else if ( format == QLatin1String( 
"d hh" ) )
 
  611       int d = totalHours / 24;
 
  612       int h = totalHours % 24;
 
  613       ret = QStringLiteral( 
"%1 d %2" ).
 
  617     else if ( format == QLatin1String( 
"d" ) )
 
  619       int d = totalHours / 24;
 
  620       ret = QString::number( d );
 
  622     else if ( format == QLatin1String( 
"ss" ) )
 
  624       int seconds = 
static_cast<int>( hours * 3600.0 );
 
  625       ret = QString::number( seconds );
 
  629       ret = QString::number( hours );
 
  635 QVector<QVector3D> QgsMeshLayerUtils::calculateNormals( 
const QgsTriangularMesh &triangularMesh, 
const QVector<double> &verticalMagnitude, 
bool isRelative )
 
  637   QVector<QVector3D> normals( triangularMesh.
vertices().count() );
 
  638   for ( 
const auto &face : triangularMesh.
triangles() )
 
  640     for ( 
int i = 0; i < 3; i++ )
 
  642       int index( face.at( i ) );
 
  643       int index1( face.at( ( i + 1 ) % 3 ) );
 
  644       int index2( face.at( ( i + 2 ) % 3 ) );
 
  650       float adjustRelative = 0;
 
  651       float adjustRelative1 = 0;
 
  652       float adjustRelative2 = 0;
 
  656         adjustRelative = vert.z();
 
  657         adjustRelative1 = otherVert1.z();
 
  658         adjustRelative2 = otherVert2.z();
 
  661       QVector3D v1( 
float( otherVert1.x() - vert.x() ),
 
  662                     float( otherVert1.y() - vert.y() ),
 
  663                     float( verticalMagnitude[index1] - verticalMagnitude[index] + adjustRelative1 - adjustRelative ) );
 
  664       QVector3D v2( 
float( otherVert2.x() - vert.x() ),
 
  665                     float( otherVert2.y() - vert.y() ),
 
  666                     float( verticalMagnitude[index2] - verticalMagnitude[index] + adjustRelative2 - adjustRelative ) );
 
  668       normals[index] += QVector3D::crossProduct( v1, v2 );
 
Perform transforms between map coordinates and device coordinates.
QgsPointXY transform(const QgsPointXY &p) const
Transform the 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.