QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsmeshtracerenderer.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmeshtracerenderer.h
3  -------------------------
4  begin : November 2019
5  copyright : (C) 2019 by Vincent Cloarec
6  email : vcloarec at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #ifndef QGSMESHTRACERENDERER_H
19 #define QGSMESHTRACERENDERER_H
20 
21 
22 #include <QVector>
23 #include <QSize>
24 
25 #include "qgis_core.h"
26 #include "qgis.h"
27 #include "qgstriangularmesh.h"
28 #include "qgsmeshlayer.h"
29 #include "qgsmeshlayerutils.h"
30 #include "qgsmeshvectorrenderer.h"
31 
33 
34 #ifndef SIP_RUN
35 
44 class QgsMeshVectorValueInterpolator
45 {
46  public:
48  QgsMeshVectorValueInterpolator( const QgsTriangularMesh &triangularMesh,
49  const QgsMeshDataBlock &datasetVectorValues );
50 
52  QgsMeshVectorValueInterpolator( const QgsTriangularMesh &triangularMesh,
53  const QgsMeshDataBlock &datasetVectorValues,
54  const QgsMeshDataBlock &scalarActiveFaceFlagValues );
55 
57  QgsMeshVectorValueInterpolator( const QgsMeshVectorValueInterpolator &other );
58 
60  virtual QgsMeshVectorValueInterpolator *clone() = 0;
61 
63  virtual ~QgsMeshVectorValueInterpolator() = default;
64 
69  virtual QgsVector vectorValue( const QgsPointXY &point ) const;
70 
72  QgsMeshVectorValueInterpolator &operator=( const QgsMeshVectorValueInterpolator &other );
73 
74  protected:
75  void updateCacheFaceIndex( const QgsPointXY &point ) const;
76 
77  QgsTriangularMesh mTriangularMesh;
78  QgsMeshDataBlock mDatasetValues;
79  QgsMeshDataBlock mActiveFaceFlagValues;
80  mutable QgsMeshFace mFaceCache;
81  mutable int mCacheFaceIndex = -1;
82  bool mUseScalarActiveFaceFlagValues = false;
83  bool isVectorValid( const QgsVector &v ) const;
84 
85  private:
86 
87  void activeFaceFilter( QgsVector &vector, int faceIndex ) const;
88 
89  virtual QgsVector interpolatedValuePrivate( int faceIndex, const QgsPointXY point ) const = 0;
90 };
91 
100 class QgsMeshVectorValueInterpolatorFromVertex: public QgsMeshVectorValueInterpolator
101 {
102  public:
104  QgsMeshVectorValueInterpolatorFromVertex( const QgsTriangularMesh &triangularMesh,
105  const QgsMeshDataBlock &datasetVectorValues );
106 
108  QgsMeshVectorValueInterpolatorFromVertex( const QgsTriangularMesh &triangularMesh,
109  const QgsMeshDataBlock &datasetVectorValues,
110  const QgsMeshDataBlock &scalarActiveFaceFlagValues );
111 
113  QgsMeshVectorValueInterpolatorFromVertex( const QgsMeshVectorValueInterpolatorFromVertex &other );
114 
116  virtual QgsMeshVectorValueInterpolatorFromVertex *clone() override;
117 
119  QgsMeshVectorValueInterpolatorFromVertex &operator=( const QgsMeshVectorValueInterpolatorFromVertex &other );
120 
121  private:
122  QgsVector interpolatedValuePrivate( int faceIndex, const QgsPointXY point ) const override;
123 };
124 
133 class QgsMeshVectorValueInterpolatorFromFace: public QgsMeshVectorValueInterpolator
134 {
135  public:
137  QgsMeshVectorValueInterpolatorFromFace( const QgsTriangularMesh &triangularMesh,
138  const QgsMeshDataBlock &datasetVectorValues );
139 
141  QgsMeshVectorValueInterpolatorFromFace( const QgsTriangularMesh &triangularMesh,
142  const QgsMeshDataBlock &datasetVectorValues,
143  const QgsMeshDataBlock &scalarActiveFaceFlagValues );
144 
146  QgsMeshVectorValueInterpolatorFromFace( const QgsMeshVectorValueInterpolatorFromFace &other );
147 
149  virtual QgsMeshVectorValueInterpolatorFromFace *clone() override;
150 
152  QgsMeshVectorValueInterpolatorFromFace &operator=( const QgsMeshVectorValueInterpolatorFromFace &other );
153 
154  private:
155  QgsVector interpolatedValuePrivate( int faceIndex, const QgsPointXY point ) const override;
156 };
157 
166 class QgsMeshStreamField
167 {
168  public:
169  struct FieldData
170  {
171  double magnitude;
172  float time;
173  int directionX;
174  int directionY;
175  };
176 
178  QgsMeshStreamField( const QgsTriangularMesh &triangularMesh,
179  const QgsMeshDataBlock &dataSetVectorValues,
180  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
181  const QgsRectangle &layerExtent,
182  double magnitudeMaximum,
183  bool dataIsOnVertices,
184  const QgsRenderContext &rendererContext,
185  const QgsInterpolatedLineColor &vectorColoring,
186  int resolution = 1 );
187 
189  QgsMeshStreamField( const QgsMeshStreamField &other );
190 
192  virtual ~QgsMeshStreamField();
193 
200  void updateSize( const QgsRenderContext &renderContext );
201 
206  void updateSize( const QgsRenderContext &renderContext, int resolution );
207 
209  bool isValid() const;
210 
212  QSize size() const;
213 
215  QPoint topLeft() const;
216 
218  void addTrace( QPoint startPixel );
219 
221  void addTrace( QgsPointXY startPoint );
222 
224  void addRandomTraces();
225 
227  void addRandomTrace();
228 
230  void addGriddedTraces( int dx, int dy );
231 
233  void addTracesOnMesh( const QgsTriangularMesh &mesh, const QgsRectangle &extent );
234 
236  void setResolution( int width );
237 
239  int resolution() const;
240 
242  QSize imageSize() const;
243 
245  virtual QImage image();
246 
248  void setPixelFillingDensity( double maxFilling );
249 
251  void setColor( QColor color );
252 
254  void setLineWidth( double width );
255 
257  void setFilter( double min, double max );
258 
260  void setMinimizeFieldSize( bool minimizeFieldSize );
261 
263  QgsMeshStreamField &operator=( const QgsMeshStreamField &other );
264 
265  protected:
266  void initImage();
267  QPointF fieldToDevice( const QPoint &pixel ) const;
268  bool filterMag( double value ) const;
269 
270  private:
271  QgsPointXY positionToMapCoordinates( const QPoint &pixelPosition, const QgsPointXY &positionInPixel );
272  bool addPixelToChunkTrace( QPoint &pixel,
273  QgsMeshStreamField::FieldData &data,
274  std::list<QPair<QPoint, QgsMeshStreamField::FieldData> > &chunkTrace );
275  void setChunkTrace( std::list<QPair<QPoint, FieldData>> &chunkTrace );
276  virtual void drawChunkTrace( const std::list<QPair<QPoint, FieldData>> &chunkTrace ) = 0;
277  void clearChunkTrace( std::list<QPair<QPoint, FieldData>> &chunkTrace );
278  virtual void storeInField( const QPair<QPoint, FieldData> pixelData ) = 0;
279  virtual void initField() = 0;
280  void simplifyChunkTrace( std::list<QPair<QPoint, FieldData>> &shunkTrace );
281 
282  virtual bool isTraceExists( const QPoint &pixel ) const = 0;
283  bool isTraceOutside( const QPoint &pixel ) const;
284 
285  protected:
286 
287  QSize mFieldSize;
288  std::unique_ptr<QPainter> mPainter = std::unique_ptr<QPainter>( nullptr );
289  int mFieldResolution = 1;
290  QPen mPen;
291  QImage mTraceImage;
292 
293  QgsMapToPixel mMapToFieldPixel;
294  QgsInterpolatedLineColor mVectorColoring;
295 
296  private:
297  int mPixelFillingCount = 0;
298  int mMaxPixelFillingCount = 0;
299  std::unique_ptr<QgsMeshVectorValueInterpolator> mVectorValueInterpolator;
300  QgsRectangle mLayerExtent;
301  QgsRectangle mMapExtent;
302  QPoint mFieldTopLeftInDeviceCoordinates;
303  bool mValid = false;
304  double mMaximumMagnitude = 0;
305  double mPixelFillingDensity = 0;
306  double mMinMagFilter = -1;
307  double mMaxMagFilter = -1;
308  const QgsRenderContext &mRenderContext; //keep the renderer context only to know if the renderer is stopped
309  bool mMinimizeFieldSize = true; //
310 };
311 
320 class QgsMeshStreamlinesField: public QgsMeshStreamField
321 {
322  public:
324  QgsMeshStreamlinesField( const QgsTriangularMesh &triangularMesh,
325  const QgsMeshDataBlock &datasetVectorValues,
326  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
327  const QgsRectangle &layerExtent,
328  double magMax,
329  bool dataIsOnVertices,
330  QgsRenderContext &rendererContext,
331  const QgsInterpolatedLineColor vectorColoring );
332 
334  QgsMeshStreamlinesField( const QgsMeshStreamlinesField &other );
335 
337  QgsMeshStreamlinesField &operator=( const QgsMeshStreamlinesField &other );
338 
339  private:
340  void storeInField( const QPair<QPoint, FieldData> pixelData ) override;
341  void initField() override;
342  bool isTraceExists( const QPoint &pixel ) const override;
343  void drawChunkTrace( const std::list<QPair<QPoint, FieldData> > &chunkTrace ) override;
344 
345  QVector<bool> mField;
346 
347 };
348 
349 class QgsMeshParticleTracesField;
350 
359 struct QgsMeshTraceParticle
360 {
361  double lifeTime = 0;
362  QPoint position;
363  std::list<QPoint> tail;
364  double remainingTime = 0; //time remaining to spend in the current pixel at the end of the time step
365 };
366 
375 class QgsMeshParticleTracesField: public QgsMeshStreamField
376 {
377  public:
379  QgsMeshParticleTracesField( const QgsTriangularMesh &triangularMesh,
380  const QgsMeshDataBlock &datasetVectorValues,
381  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
382  const QgsRectangle &layerExtent,
383  double magMax,
384  bool dataIsOnVertices,
385  const QgsRenderContext &rendererContext,
386  const QgsInterpolatedLineColor vectorColoring );
387 
389  QgsMeshParticleTracesField( const QgsMeshParticleTracesField &other );
390 
392  void addParticle( const QPoint &startPoint, double lifeTime );
393 
395  void addParticleXY( const QgsPointXY &startPoint, double lifeTime );
396 
398  void addRandomParticles();
399 
401  void moveParticles();
402 
404  QImage imageRendered() const;
405 
407  void setParticlesCount( int particlesCount );
408 
410  void setParticlesLifeTime( double particlesLifeTime );
411 
413  void stump();
414 
420  void setStumpFactor( int sf );
421 
423  void setTimeStep( double timeStep );
424 
426  void setParticleSize( double particleSize );
427 
429  void setTailFactor( double tailFactor );
430 
432  void setMinTailLength( int minTailLength );
433 
435  QgsMeshParticleTracesField &operator=( const QgsMeshParticleTracesField &other );
436 
438  void setStumpParticleWithLifeTime( bool stumpParticleWithLifeTime );
439 
441  void setParticlesColor( const QColor &c );
442  private:
443  QPoint direction( QPoint position ) const;
444 
445  float time( QPoint position ) const;
446  float magnitude( QPoint position ) const;
447 
448  void drawParticleTrace( const QgsMeshTraceParticle &particle );
449 
450  void storeInField( const QPair<QPoint, FieldData> pixelData ) override;
451  void initField() override;
452  bool isTraceExists( const QPoint &pixel ) const override;
453  void drawChunkTrace( const std::list<QPair<QPoint, FieldData>> &chunkTrace ) override {Q_UNUSED( chunkTrace )}
454 
455  /* Nondimensional time
456  * This field store the time spent by the particle in the pixel
457  *
458  * This time is nondimensional and value 1 is equivalent to the time spent by the particle in a pixel
459  * for Vmax, the maximum magnitude of the vector field.
460  *
461  */
462  QVector<float> mTimeField;
463  QVector<float> mMagnitudeField;
464 
465  /*the direction for a pixel is defined with a char value
466  *
467  * 1 2 3
468  * 4 5 6
469  * 7 8 9
470  *
471  * convenient to retrieve the indexes of the next pixel from the direction d:
472  * Xnext= (d-1)%3-1
473  * Ynext = (d-1)/3-1
474  *
475  * and the direction is defined by :
476  * d=incX + 2 + (incY+1)*3
477  */
478  QVector<char> mDirectionField;
479  QList<QgsMeshTraceParticle> mParticles;
480  QImage mStumpImage;
481 
482  double mTimeStep = 200;
483  double mParticlesLifeTime = 5000;
484  int mParticlesCount = 1000;
485  double mTailFactor = 5;
486  int mMinTailLength = 3;
487  QColor mParticleColor = Qt::white;
488  double mParticleSize = 2.5;
489  int mStumpFactor = 50;
490  bool mStumpParticleWithLifeTime = true;
491 };
492 
503 class QgsMeshVectorStreamlineRenderer: public QgsMeshVectorRenderer
504 {
505  public:
507  QgsMeshVectorStreamlineRenderer( const QgsTriangularMesh &triangularMesh,
508  const QgsMeshDataBlock &dataSetVectorValues,
509  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
510  bool dataIsOnVertices,
511  const QgsMeshRendererVectorSettings &settings,
512  QgsRenderContext &rendererContext,
513  const QgsRectangle &layerExtent,
514  double magMax );
515 
516  void draw() override;
517 
518  private:
519  std::unique_ptr<QgsMeshStreamField> mStreamlineField;
520  QgsRenderContext &mRendererContext;
521 };
522 
523 
534 class QgsMeshVectorTraceRenderer: public QgsMeshVectorRenderer
535 {
536  public:
538  QgsMeshVectorTraceRenderer( const QgsTriangularMesh &triangularMesh,
539  const QgsMeshDataBlock &dataSetVectorValues,
540  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
541  bool dataIsOnVertices,
542  const QgsMeshRendererVectorSettings &settings,
543  QgsRenderContext &rendererContext,
544  const QgsRectangle &layerExtent,
545  double magMax );
546 
547  void draw() override;
548 
549  private:
550  std::unique_ptr<QgsMeshParticleTracesField> mParticleField;
551  QgsRenderContext &mRendererContext;
552 };
553 
554 
555 #endif //SIP_RUN
556 
558 
567 {
568  public:
571  const QgsMeshDataBlock &dataSetVectorValues,
572  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
573  bool dataIsOnVertices,
574  const QgsRenderContext &rendererContext,
575  const QgsRectangle &layerExtent,
576  double magMax,
577  const QgsMeshRendererVectorSettings &vectorSettings ) SIP_SKIP;
578 
580  QgsMeshVectorTraceAnimationGenerator( QgsMeshLayer *layer, const QgsRenderContext &rendererContext );
581 
584 
587 
589  void seedRandomParticles( int count );
590 
592  QImage imageRendered();
593 
595  void setFPS( int FPS );
596 
598  void setMaxSpeedPixel( int max );
599 
601  void setParticlesLifeTime( double particleLifeTime );
602 
604  void setParticlesColor( const QColor &c );
605 
607  void setParticlesSize( double width );
608 
610  void setTailFactor( double fct );
611 
613  void setMinimumTailLength( int l );
614 
616  void setTailPersitence( double p );
617 
620  private:
621  std::unique_ptr<QgsMeshParticleTracesField> mParticleField;
622  const QgsRenderContext &mRendererContext;
623  int mFPS = 15; //frame per second of the output, used to calculate orher parameters of the field
624  int mVpixMax = 2000; //is the number of pixels that are going through for 1 s
625  double mParticleLifeTime = 5;
626 
627  void updateFieldParameter();
628 };
629 
630 #endif // QGSMESHTRACERENDERER_H
qgsmeshlayerutils.h
QgsMeshRendererVectorSettings
Represents a renderer settings for vector datasets.
Definition: qgsmeshrenderersettings.h:410
qgis.h
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:59
QgsMeshVectorTraceAnimationGenerator
A wrapper for QgsMeshParticuleTracesField used to render the particles. Available for Python binding.
Definition: qgsmeshtracerenderer.h:566
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
qgstriangularmesh.h
SIP_SKIP
#define SIP_SKIP
Definition: qgis_sip.h:126
QgsMeshLayer
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:98
QgsInterpolatedLineColor
Class defining color to render mesh datasets. The color can vary depending on the dataset value.
Definition: qgsinterpolatedlinerenderer.h:38
QgsMeshFace
QVector< int > QgsMeshFace
List of vertex indexes.
Definition: qgsmeshdataprovider.h:42
qgsmeshlayer.h
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:58
c
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
Definition: porting_processing.dox:1
QgsMapToPixel
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:38
qgsmeshvectorrenderer.h
QgsVector
A class to represent a vector. Currently no Z axis / 2.5D support is implemented.
Definition: qgsvector.h:29
QgsMeshDataBlock
QgsMeshDataBlock is a block of integers/doubles that can be used to retrieve: active flags (e....
Definition: qgsmeshdataset.h:137
QgsTriangularMesh
Triangular/Derived Mesh is mesh with vertices in map coordinates.
Definition: qgstriangularmesh.h:51