QGIS API Documentation  3.23.0-Master (dd0cd13a00)
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 
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
Class defining color to render mesh datasets.
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:39
QgsMeshDataBlock is a block of integers/doubles that can be used to retrieve: active flags (e....
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:97
Represents a renderer settings for vector datasets.
A wrapper for QgsMeshParticuleTracesField used to render the particles.
void setParticlesLifeTime(double particleLifeTime)
Sets maximum life time of particles in seconds.
void setMinimumTailLength(int l)
Sets the minimum tail length.
QgsMeshVectorTraceAnimationGenerator(const QgsMeshVectorTraceAnimationGenerator &other)
Copy constructor.
void setTailPersitence(double p)
Sets the visual persistence of the tail.
void setParticlesColor(const QColor &c)
Sets colors of particle.
QImage imageRendered()
Moves all the particles using frame per second (fps) to calculate the displacement and return the ren...
QgsMeshVectorTraceAnimationGenerator(QgsMeshLayer *layer, const QgsRenderContext &rendererContext)
Constructor to use with Python binding.
void setTailFactor(double fct)
Sets the tail factor, used to adjust the length of the tail. 0 : minimum length, >1 increase the tail...
~QgsMeshVectorTraceAnimationGenerator()=default
Destructor.
void setFPS(int FPS)
Sets the number of frames per seconds that will be rendered.
QgsMeshVectorTraceAnimationGenerator(const QgsTriangularMesh &triangularMesh, const QgsMeshDataBlock &dataSetVectorValues, const QgsMeshDataBlock &scalarActiveFaceFlagValues, bool dataIsOnVertices, const QgsRenderContext &rendererContext, const QgsRectangle &layerExtent, double magMax, const QgsMeshRendererVectorSettings &vectorSettings)
Constructor to use from QgsMeshVectorRenderer.
void setParticlesSize(double width)
Sets particle size in px.
void setMaxSpeedPixel(int max)
Sets the max number of pixels that can be go through by the particles in 1 second.
QgsMeshVectorTraceAnimationGenerator & operator=(const QgsMeshVectorTraceAnimationGenerator &other)
Assignment operator.
void seedRandomParticles(int count)
seeds particles in the vector fields
A class to represent a 2D point.
Definition: qgspointxy.h:59
A rectangle specified with double values.
Definition: qgsrectangle.h:42
Contains information about the context of a rendering operation.
Triangular/Derived Mesh is mesh with vertices in map coordinates.
A class to represent a vector.
Definition: qgsvector.h:30
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
#define SIP_SKIP
Definition: qgis_sip.h:126
QVector< int > QgsMeshFace
List of vertex indexes.