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 )
248 if ( pA == pB || pA == pC || pB == pC )
257 double dot00 = v0 * v0;
258 double dot01 = v0 * v1;
259 double dot02 = v0 * v2;
260 double dot11 = v1 * v1;
261 double dot12 = v1 * v2;
264 double invDenom = 1.0 / ( dot00 * dot11 - dot01 * dot01 );
265 lam1 = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
266 lam2 = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
267 lam3 = 1.0 - lam1 - lam2;
275 if ( ( lam1 < 0 ) || ( lam2 < 0 ) || ( lam3 < 0 ) )
284 double val1,
double val2,
double val3,
const QgsPointXY &pt )
286 double lam1, lam2, lam3;
287 if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
288 return std::numeric_limits<double>::quiet_NaN();
290 return lam1 * val3 + lam2 * val2 + lam3 * val1;
293 double QgsMeshLayerUtils::interpolateFromVerticesData(
double fraction,
double val1,
double val2 )
295 if ( std::isnan( val1 ) || std::isnan( val2 ) || ( fraction < 0 ) || ( fraction > 1 ) )
297 return std::numeric_limits<double>::quiet_NaN();
299 return val1 + ( val2 - val1 ) * fraction;
305 interpolateFromVerticesData( fraction, val1.
y(), val2.
y() ) );
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() );
315 return vect3 * lam1 + vect2 * lam2 + vect1 * lam3;
321 double lam1, lam2, lam3;
322 if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
323 return std::numeric_limits<double>::quiet_NaN();
331 double lam1, lam2, lam3;
332 if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
333 return QgsVector( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
339 QVector<double> QgsMeshLayerUtils::interpolateFromFacesData(
340 QVector<double> valuesOnFaces,
346 assert( nativeMesh );
352 int vertexCount = triangularMesh->
vertices().size();
354 QVector<double> res( vertexCount, 0.0 );
356 QVector<int> count( vertexCount, 0 );
358 for (
int i = 0; i < nativeMesh->
faces.size(); ++i )
360 if ( !active || active->
active( i ) )
362 double val = valuesOnFaces[ i ];
363 if ( !std::isnan( val ) )
367 for (
int j = 0; j < face.size(); ++j )
369 int vertexIndex = face[j];
370 res[vertexIndex] += val;
371 count[vertexIndex] += 1;
377 for (
int i = 0; i < vertexCount; ++i )
379 if ( count.at( i ) > 0 )
381 res[i] = res[i] / double( count.at( i ) );
385 res[i] = std::numeric_limits<double>::quiet_NaN();
392 QVector<double> QgsMeshLayerUtils::resampleFromVerticesToFaces(
393 const QVector<double> valuesOnVertices,
399 assert( nativeMesh );
404 Q_UNUSED( triangularMesh );
407 QVector<double> ret( nativeMesh->
faceCount(), std::numeric_limits<double>::quiet_NaN() );
409 for (
int i = 0; i < nativeMesh->
faces.size(); ++i )
412 if ( active->
active( i ) && face.count() > 2 )
415 for (
int j = 0; j < face.count(); ++j )
417 value += valuesOnVertices.at( face.at( j ) );
419 ret[i] = value / face.count();
426 QVector<double> QgsMeshLayerUtils::calculateMagnitudeOnVertices(
const QgsMeshLayer *meshLayer,
433 if ( !meshLayer && !index.
isValid() )
438 if ( !triangularMesh || !nativeMesh )
445 int datacount = scalarDataOnVertices ? nativeMesh->
vertices.count() : nativeMesh->
faces.count();
454 ret = QgsMeshLayerUtils::calculateMagnitudes( vals );
456 if ( !scalarDataOnVertices )
459 ret = QgsMeshLayerUtils::interpolateFromFacesData(
463 activeFaceFlagValues,
473 double xMin = p1.
x();
474 double xMax = p1.
x();
475 double yMin = p1.
y();
476 double yMax = p1.
y();
479 xMin = ( ( xMin < p2.
x() ) ? xMin : p2.
x() );
480 xMax = ( ( xMax > p2.
x() ) ? xMax : p2.
x() );
481 yMin = ( ( yMin < p2.
y() ) ? yMin : p2.
y() );
482 yMax = ( ( yMax > p2.
y() ) ? yMax : p2.
y() );
485 xMin = ( ( xMin < p3.
x() ) ? xMin : p3.
x() );
486 xMax = ( ( xMax > p3.
x() ) ? xMax : p3.
x() );
487 yMin = ( ( yMin < p3.
y() ) ? yMin : p3.
y() );
488 yMax = ( ( yMax > p3.
y() ) ? yMax : p3.
y() );
494 QString QgsMeshLayerUtils::formatTime(
double hours,
const QDateTime &referenceTime,
const QgsMeshTimeSettings &settings )
498 if ( referenceTime.isValid() )
501 QDateTime dateTime( referenceTime );
502 qint64 seconds =
static_cast<qint64
>( hours * 3600.0 );
503 dateTime = dateTime.addSecs( seconds );
504 ret = dateTime.toString( format );
506 ret = dateTime.toString();
511 format = format.trimmed();
512 int totalHours =
static_cast<int>( hours );
514 if ( format == QLatin1String(
"hh:mm:ss.zzz" ) )
516 int ms =
static_cast<int>( hours * 3600.0 * 1000 );
517 int seconds = ms / 1000;
519 int m = seconds / 60;
520 int s = seconds % 60;
523 ret = QStringLiteral(
"%1:%2:%3.%4" ).
524 arg( h, 2, 10, QLatin1Char(
'0' ) ).
525 arg( m, 2, 10, QLatin1Char(
'0' ) ).
526 arg( s, 2, 10, QLatin1Char(
'0' ) ).
527 arg( z, 3, 10, QLatin1Char(
'0' ) );
529 else if ( format == QLatin1String(
"hh:mm:ss" ) )
531 int seconds =
static_cast<int>( hours * 3600.0 );
532 int m = seconds / 60;
533 int s = seconds % 60;
536 ret = QStringLiteral(
"%1:%2:%3" ).
537 arg( h, 2, 10, QLatin1Char(
'0' ) ).
538 arg( m, 2, 10, QLatin1Char(
'0' ) ).
539 arg( s, 2, 10, QLatin1Char(
'0' ) );
542 else if ( format == QLatin1String(
"d hh:mm:ss" ) )
544 int seconds =
static_cast<int>( hours * 3600.0 );
545 int m = seconds / 60;
546 int s = seconds % 60;
549 int d = totalHours / 24;
551 ret = QStringLiteral(
"%1 d %2:%3:%4" ).
553 arg( h, 2, 10, QLatin1Char(
'0' ) ).
554 arg( m, 2, 10, QLatin1Char(
'0' ) ).
555 arg( s, 2, 10, QLatin1Char(
'0' ) );
557 else if ( format == QLatin1String(
"d hh" ) )
559 int d = totalHours / 24;
560 int h = totalHours % 24;
561 ret = QStringLiteral(
"%1 d %2" ).
565 else if ( format == QLatin1String(
"d" ) )
567 int d = totalHours / 24;
568 ret = QString::number( d );
570 else if ( format == QLatin1String(
"ss" ) )
572 int seconds =
static_cast<int>( hours * 3600.0 );
573 ret = QString::number( seconds );
577 ret = QString::number( hours );
583 QVector<QVector3D> QgsMeshLayerUtils::calculateNormals(
const QgsTriangularMesh &triangularMesh,
const QVector<double> &verticalMagnitude,
bool isRelative )
585 QVector<QVector3D> normals( triangularMesh.
vertices().count() );
586 for (
const auto &face : triangularMesh.
triangles() )
588 for (
int i = 0; i < 3; i++ )
590 int index( face.at( i ) );
591 int index1( face.at( ( i + 1 ) % 3 ) );
592 int index2( face.at( ( i + 2 ) % 3 ) );
598 float adjustRelative = 0;
599 float adjustRelative1 = 0;
600 float adjustRelative2 = 0;
604 adjustRelative = vert.z();
605 adjustRelative1 = otherVert1.z();
606 adjustRelative2 = otherVert2.z();
609 QVector3D v1(
float( otherVert1.x() - vert.x() ),
610 float( otherVert1.y() - vert.y() ),
611 float( verticalMagnitude[index1] - verticalMagnitude[index] + adjustRelative1 - adjustRelative ) );
612 QVector3D v2(
float( otherVert2.x() - vert.x() ),
613 float( otherVert2.y() - vert.y() ),
614 float( verticalMagnitude[index2] - verticalMagnitude[index] + adjustRelative2 - adjustRelative ) );
616 normals[index] += QVector3D::crossProduct( v1, v2 );