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 void QgsMeshLayerUtils::boundingBoxToScreenRectangle(
const QgsMapToPixel &mtp,
201 const QSize &outputSize,
210 topLim = std::max(
int( ur.
y() ), 0 );
211 bottomLim = std::min(
int( ll.
y() ), outputSize.height() - 1 );
212 leftLim = std::max(
int( ll.
x() ), 0 );
213 rightLim = std::min(
int( ur.
x() ), outputSize.width() - 1 );
216 static void lamTol(
double &lam )
218 const static double eps = 1e-6;
219 if ( ( lam < 0.0 ) && ( lam > -eps ) )
226 double &lam1,
double &lam2,
double &lam3 )
228 if ( pA == pB || pA == pC || pB == pC )
237 double dot00 = v0 * v0;
238 double dot01 = v0 * v1;
239 double dot02 = v0 * v2;
240 double dot11 = v1 * v1;
241 double dot12 = v1 * v2;
244 double invDenom = 1.0 / ( dot00 * dot11 - dot01 * dot01 );
245 lam1 = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
246 lam2 = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
247 lam3 = 1.0 - lam1 - lam2;
255 if ( ( lam1 < 0 ) || ( lam2 < 0 ) || ( lam3 < 0 ) )
264 double val1,
double val2,
double val3,
const QgsPointXY &pt )
266 double lam1, lam2, lam3;
267 if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
268 return std::numeric_limits<double>::quiet_NaN();
270 return lam1 * val3 + lam2 * val2 + lam3 * val1;
273 double QgsMeshLayerUtils::interpolateFromVerticesData(
double fraction,
double val1,
double val2 )
275 if ( std::isnan( val1 ) || std::isnan( val2 ) || ( fraction < 0 ) || ( fraction > 1 ) )
277 return std::numeric_limits<double>::quiet_NaN();
279 return val1 + ( val2 - val1 ) * fraction;
285 interpolateFromVerticesData( fraction, val1.
y(), val2.
y() ) );
291 double lam1, lam2, lam3;
292 if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
293 return QgsVector( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
295 return vect3 * lam1 + vect2 * lam2 + vect1 * lam3;
301 double lam1, lam2, lam3;
302 if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
303 return std::numeric_limits<double>::quiet_NaN();
311 double lam1, lam2, lam3;
312 if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
313 return QgsVector( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
319 QVector<double> QgsMeshLayerUtils::interpolateFromFacesData(
320 QVector<double> valuesOnFaces,
326 assert( nativeMesh );
332 int vertexCount = triangularMesh->
vertices().size();
334 QVector<double> res( vertexCount, 0.0 );
336 QVector<int> count( vertexCount, 0 );
338 for (
int i = 0; i < nativeMesh->
faces.size(); ++i )
340 if ( !active || active->
active( i ) )
342 double val = valuesOnFaces[ i ];
343 if ( !std::isnan( val ) )
347 for (
int j = 0; j < face.size(); ++j )
349 int vertexIndex = face[j];
350 res[vertexIndex] += val;
351 count[vertexIndex] += 1;
357 for (
int i = 0; i < vertexCount; ++i )
359 if ( count.at( i ) > 0 )
361 res[i] = res[i] / double( count.at( i ) );
365 res[i] = std::numeric_limits<double>::quiet_NaN();
372 QVector<double> QgsMeshLayerUtils::resampleFromVerticesToFaces(
373 const QVector<double> valuesOnVertices,
379 assert( nativeMesh );
384 Q_UNUSED( triangularMesh );
387 QVector<double> ret( nativeMesh->
faceCount(), std::numeric_limits<double>::quiet_NaN() );
389 for (
int i = 0; i < nativeMesh->
faces.size(); ++i )
392 if ( active->
active( i ) && face.count() > 2 )
395 for (
int j = 0; j < face.count(); ++j )
397 value += valuesOnVertices.at( face.at( j ) );
399 ret[i] = value / face.count();
406 QVector<double> QgsMeshLayerUtils::calculateMagnitudeOnVertices(
const QgsMeshLayer *meshLayer,
413 if ( !meshLayer && !index.
isValid() )
418 if ( !triangularMesh || !nativeMesh )
425 int datacount = scalarDataOnVertices ? nativeMesh->
vertices.count() : nativeMesh->
faces.count();
434 ret = QgsMeshLayerUtils::calculateMagnitudes( vals );
436 if ( !scalarDataOnVertices )
439 ret = QgsMeshLayerUtils::interpolateFromFacesData(
443 activeFaceFlagValues,
453 double xMin = p1.
x();
454 double xMax = p1.
x();
455 double yMin = p1.
y();
456 double yMax = p1.
y();
459 xMin = ( ( xMin < p2.
x() ) ? xMin : p2.
x() );
460 xMax = ( ( xMax > p2.
x() ) ? xMax : p2.
x() );
461 yMin = ( ( yMin < p2.
y() ) ? yMin : p2.
y() );
462 yMax = ( ( yMax > p2.
y() ) ? yMax : p2.
y() );
465 xMin = ( ( xMin < p3.
x() ) ? xMin : p3.
x() );
466 xMax = ( ( xMax > p3.
x() ) ? xMax : p3.
x() );
467 yMin = ( ( yMin < p3.
y() ) ? yMin : p3.
y() );
468 yMax = ( ( yMax > p3.
y() ) ? yMax : p3.
y() );
474 QString QgsMeshLayerUtils::formatTime(
double hours,
const QDateTime &referenceTime,
const QgsMeshTimeSettings &settings )
478 if ( referenceTime.isValid() )
481 QDateTime dateTime( referenceTime );
482 qint64 seconds =
static_cast<qint64
>( hours * 3600.0 );
483 dateTime = dateTime.addSecs( seconds );
484 ret = dateTime.toString( format );
486 ret = dateTime.toString();
491 format = format.trimmed();
492 int totalHours =
static_cast<int>( hours );
494 if ( format == QStringLiteral(
"hh:mm:ss.zzz" ) )
496 int ms =
static_cast<int>( hours * 3600.0 * 1000 );
497 int seconds = ms / 1000;
499 int m = seconds / 60;
500 int s = seconds % 60;
503 ret = QStringLiteral(
"%1:%2:%3.%4" ).
504 arg( h, 2, 10, QLatin1Char(
'0' ) ).
505 arg( m, 2, 10, QLatin1Char(
'0' ) ).
506 arg( s, 2, 10, QLatin1Char(
'0' ) ).
507 arg( z, 3, 10, QLatin1Char(
'0' ) );
509 else if ( format == QStringLiteral(
"hh:mm:ss" ) )
511 int seconds =
static_cast<int>( hours * 3600.0 );
512 int m = seconds / 60;
513 int s = seconds % 60;
516 ret = QStringLiteral(
"%1:%2:%3" ).
517 arg( h, 2, 10, QLatin1Char(
'0' ) ).
518 arg( m, 2, 10, QLatin1Char(
'0' ) ).
519 arg( s, 2, 10, QLatin1Char(
'0' ) );
522 else if ( format == QStringLiteral(
"d hh:mm:ss" ) )
524 int seconds =
static_cast<int>( hours * 3600.0 );
525 int m = seconds / 60;
526 int s = seconds % 60;
529 int d = totalHours / 24;
531 ret = QStringLiteral(
"%1 d %2:%3:%4" ).
533 arg( h, 2, 10, QLatin1Char(
'0' ) ).
534 arg( m, 2, 10, QLatin1Char(
'0' ) ).
535 arg( s, 2, 10, QLatin1Char(
'0' ) );
537 else if ( format == QStringLiteral(
"d hh" ) )
539 int d = totalHours / 24;
540 int h = totalHours % 24;
541 ret = QStringLiteral(
"%1 d %2" ).
545 else if ( format == QStringLiteral(
"d" ) )
547 int d = totalHours / 24;
548 ret = QStringLiteral(
"%1" ).arg( d );
550 else if ( format == QStringLiteral(
"ss" ) )
552 int seconds =
static_cast<int>( hours * 3600.0 );
553 ret = QStringLiteral(
"%1" ).arg( seconds );
557 ret = QStringLiteral(
"%1" ).arg( hours );
563 QVector<QVector3D> QgsMeshLayerUtils::calculateNormals(
const QgsTriangularMesh &triangularMesh,
const QVector<double> &verticalMagnitude,
bool isRelative )
565 QVector<QVector3D> normals( triangularMesh.
vertices().count() );
566 for (
const auto &face : triangularMesh.
triangles() )
568 for (
int i = 0; i < 3; i++ )
570 int index( face.at( i ) );
571 int index1( face.at( ( i + 1 ) % 3 ) );
572 int index2( face.at( ( i + 2 ) % 3 ) );
578 float adjustRelative = 0;
579 float adjustRelative1 = 0;
580 float adjustRelative2 = 0;
584 adjustRelative = vert.z();
585 adjustRelative1 = otherVert1.z();
586 adjustRelative2 = otherVert2.z();
589 QVector3D v1(
float( otherVert1.x() - vert.x() ),
590 float( otherVert1.y() - vert.y() ),
591 float( verticalMagnitude[index1] - verticalMagnitude[index] + adjustRelative1 - adjustRelative ) );
592 QVector3D v2(
float( otherVert2.x() - vert.x() ),
593 float( otherVert2.y() - vert.y() ),
594 float( verticalMagnitude[index2] - verticalMagnitude[index] + adjustRelative2 - adjustRelative ) );
596 normals[index] += QVector3D::crossProduct( v1, v2 );