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 );
358 return interpolateFromFacesData( valuesOnFaces, *nativeMesh, active, method );
361 QVector<double> QgsMeshLayerUtils::interpolateFromFacesData(
const QVector<double> &valuesOnFaces,
369 QVector<double> res( vertexCount, 0.0 );
371 QVector<int> count( vertexCount, 0 );
373 for (
int i = 0; i < nativeMesh.
faceCount(); ++i )
375 if ( !active || active->
active( i ) )
377 double val = valuesOnFaces[ i ];
378 if ( !std::isnan( val ) )
382 for (
int j = 0; j < face.size(); ++j )
384 int vertexIndex = face[j];
385 res[vertexIndex] += val;
386 count[vertexIndex] += 1;
392 for (
int i = 0; i < vertexCount; ++i )
394 if ( count.at( i ) > 0 )
396 res[i] = res[i] / double( count.at( i ) );
400 res[i] = std::numeric_limits<double>::quiet_NaN();
407 QVector<double> QgsMeshLayerUtils::resampleFromVerticesToFaces(
408 const QVector<double> valuesOnVertices,
414 assert( nativeMesh );
419 Q_UNUSED( triangularMesh );
422 QVector<double> ret( nativeMesh->
faceCount(), std::numeric_limits<double>::quiet_NaN() );
424 for (
int i = 0; i < nativeMesh->
faces.size(); ++i )
427 if ( active->
active( i ) && face.count() > 2 )
430 for (
int j = 0; j < face.count(); ++j )
432 value += valuesOnVertices.at( face.at( j ) );
434 ret[i] = value / face.count();
441 QVector<double> QgsMeshLayerUtils::calculateMagnitudeOnVertices(
const QgsMeshLayer *meshLayer,
448 if ( !meshLayer && !index.
isValid() )
453 if ( !triangularMesh || !nativeMesh )
460 int datacount = scalarDataOnVertices ? nativeMesh->
vertices.count() : nativeMesh->
faces.count();
467 return calculateMagnitudeOnVertices( *nativeMesh, metadata, vals, *activeFaceFlagValues, method );
470 QVector<double> QgsMeshLayerUtils::calculateMagnitudeOnVertices(
const QgsMesh &nativeMesh,
481 ret = QgsMeshLayerUtils::calculateMagnitudes( datasetValues );
483 if ( !scalarDataOnVertices )
486 ret = QgsMeshLayerUtils::interpolateFromFacesData(
489 &activeFaceFlagValues,
499 double xMin = p1.
x();
500 double xMax = p1.
x();
501 double yMin = p1.
y();
502 double yMax = p1.
y();
505 xMin = ( ( xMin < p2.
x() ) ? xMin : p2.
x() );
506 xMax = ( ( xMax > p2.
x() ) ? xMax : p2.
x() );
507 yMin = ( ( yMin < p2.
y() ) ? yMin : p2.
y() );
508 yMax = ( ( yMax > p2.
y() ) ? yMax : p2.
y() );
511 xMin = ( ( xMin < p3.
x() ) ? xMin : p3.
x() );
512 xMax = ( ( xMax > p3.
x() ) ? xMax : p3.
x() );
513 yMin = ( ( yMin < p3.
y() ) ? yMin : p3.
y() );
514 yMax = ( ( yMax > p3.
y() ) ? yMax : p3.
y() );
520 QString QgsMeshLayerUtils::formatTime(
double hours,
const QDateTime &referenceTime,
const QgsMeshTimeSettings &settings )
524 if ( referenceTime.isValid() )
527 QDateTime dateTime( referenceTime );
528 qint64 seconds =
static_cast<qint64
>( hours * 3600.0 );
529 dateTime = dateTime.addSecs( seconds );
530 ret = dateTime.toString( format );
532 ret = dateTime.toString();
537 format = format.trimmed();
538 int totalHours =
static_cast<int>( hours );
540 if ( format == QLatin1String(
"hh:mm:ss.zzz" ) )
542 int ms =
static_cast<int>( hours * 3600.0 * 1000 );
543 int seconds = ms / 1000;
545 int m = seconds / 60;
546 int s = seconds % 60;
549 ret = QStringLiteral(
"%1:%2:%3.%4" ).
550 arg( h, 2, 10, QLatin1Char(
'0' ) ).
551 arg( m, 2, 10, QLatin1Char(
'0' ) ).
552 arg( s, 2, 10, QLatin1Char(
'0' ) ).
553 arg( z, 3, 10, QLatin1Char(
'0' ) );
555 else if ( format == QLatin1String(
"hh:mm:ss" ) )
557 int seconds =
static_cast<int>( hours * 3600.0 );
558 int m = seconds / 60;
559 int s = seconds % 60;
562 ret = QStringLiteral(
"%1:%2:%3" ).
563 arg( h, 2, 10, QLatin1Char(
'0' ) ).
564 arg( m, 2, 10, QLatin1Char(
'0' ) ).
565 arg( s, 2, 10, QLatin1Char(
'0' ) );
568 else if ( format == QLatin1String(
"d hh:mm:ss" ) )
570 int seconds =
static_cast<int>( hours * 3600.0 );
571 int m = seconds / 60;
572 int s = seconds % 60;
575 int d = totalHours / 24;
577 ret = QStringLiteral(
"%1 d %2:%3:%4" ).
579 arg( h, 2, 10, QLatin1Char(
'0' ) ).
580 arg( m, 2, 10, QLatin1Char(
'0' ) ).
581 arg( s, 2, 10, QLatin1Char(
'0' ) );
583 else if ( format == QLatin1String(
"d hh" ) )
585 int d = totalHours / 24;
586 int h = totalHours % 24;
587 ret = QStringLiteral(
"%1 d %2" ).
591 else if ( format == QLatin1String(
"d" ) )
593 int d = totalHours / 24;
594 ret = QString::number( d );
596 else if ( format == QLatin1String(
"ss" ) )
598 int seconds =
static_cast<int>( hours * 3600.0 );
599 ret = QString::number( seconds );
603 ret = QString::number( hours );
609 QVector<QVector3D> QgsMeshLayerUtils::calculateNormals(
const QgsTriangularMesh &triangularMesh,
const QVector<double> &verticalMagnitude,
bool isRelative )
611 QVector<QVector3D> normals( triangularMesh.
vertices().count() );
612 for (
const auto &face : triangularMesh.
triangles() )
614 for (
int i = 0; i < 3; i++ )
616 int index( face.at( i ) );
617 int index1( face.at( ( i + 1 ) % 3 ) );
618 int index2( face.at( ( i + 2 ) % 3 ) );
624 float adjustRelative = 0;
625 float adjustRelative1 = 0;
626 float adjustRelative2 = 0;
630 adjustRelative = vert.z();
631 adjustRelative1 = otherVert1.z();
632 adjustRelative2 = otherVert2.z();
635 QVector3D v1(
float( otherVert1.x() - vert.x() ),
636 float( otherVert1.y() - vert.y() ),
637 float( verticalMagnitude[index1] - verticalMagnitude[index] + adjustRelative1 - adjustRelative ) );
638 QVector3D v2(
float( otherVert2.x() - vert.x() ),
639 float( otherVert2.y() - vert.y() ),
640 float( verticalMagnitude[index2] - verticalMagnitude[index] + adjustRelative2 - adjustRelative ) );
642 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.
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.