QGIS API Documentation  3.12.1-BucureČ™ti (121cc00ff0)
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 
32 
34 
35 #ifndef SIP_RUN
36 
45 class QgsMeshVectorValueInterpolator
46 {
47  public:
49  QgsMeshVectorValueInterpolator( const QgsTriangularMesh &triangularMesh,
50  const QgsMeshDataBlock &datasetVectorValues );
51 
53  QgsMeshVectorValueInterpolator( const QgsTriangularMesh &triangularMesh,
54  const QgsMeshDataBlock &datasetVectorValues,
55  const QgsMeshDataBlock &scalarActiveFaceFlagValues );
56 
58  QgsMeshVectorValueInterpolator( const QgsMeshVectorValueInterpolator &other );
59 
61  virtual QgsMeshVectorValueInterpolator *clone() = 0;
62 
64  virtual ~QgsMeshVectorValueInterpolator() = default;
65 
67  virtual QgsVector vectorValue( const QgsPointXY &point ) const;
68 
70  QgsMeshVectorValueInterpolator &operator=( const QgsMeshVectorValueInterpolator &other );
71 
72  protected:
73  void updateCacheFaceIndex( const QgsPointXY &point ) const;
74 
75  QgsTriangularMesh mTriangularMesh;
76  QgsMeshDataBlock mDatasetValues;
77  QgsMeshDataBlock mActiveFaceFlagValues;
78  mutable QgsMeshFace mFaceCache;
79  mutable int mCacheFaceIndex = -1;
80  bool mUseScalarActiveFaceFlagValues = false;
81  bool isVectorValid( const QgsVector &v ) const;
82 
83  private:
84 
85  void activeFaceFilter( QgsVector &vector, int faceIndex ) const;
86 
87  virtual QgsVector interpolatedValuePrivate( int faceIndex, const QgsPointXY point ) const = 0;
88 };
89 
98 class QgsMeshVectorValueInterpolatorFromVertex: public QgsMeshVectorValueInterpolator
99 {
100  public:
102  QgsMeshVectorValueInterpolatorFromVertex( const QgsTriangularMesh &triangularMesh,
103  const QgsMeshDataBlock &datasetVectorValues );
104 
106  QgsMeshVectorValueInterpolatorFromVertex( const QgsTriangularMesh &triangularMesh,
107  const QgsMeshDataBlock &datasetVectorValues,
108  const QgsMeshDataBlock &scalarActiveFaceFlagValues );
109 
111  QgsMeshVectorValueInterpolatorFromVertex( const QgsMeshVectorValueInterpolatorFromVertex &other );
112 
114  virtual QgsMeshVectorValueInterpolatorFromVertex *clone() override;
115 
117  QgsMeshVectorValueInterpolatorFromVertex &operator=( const QgsMeshVectorValueInterpolatorFromVertex &other );
118 
119  private:
120  QgsVector interpolatedValuePrivate( int faceIndex, const QgsPointXY point ) const override;
121 };
122 
131 class QgsMeshVectorValueInterpolatorFromFace: public QgsMeshVectorValueInterpolator
132 {
133  public:
135  QgsMeshVectorValueInterpolatorFromFace( const QgsTriangularMesh &triangularMesh,
136  const QgsMeshDataBlock &datasetVectorValues );
137 
139  QgsMeshVectorValueInterpolatorFromFace( const QgsTriangularMesh &triangularMesh,
140  const QgsMeshDataBlock &datasetVectorValues,
141  const QgsMeshDataBlock &scalarActiveFaceFlagValues );
142 
144  QgsMeshVectorValueInterpolatorFromFace( const QgsMeshVectorValueInterpolatorFromFace &other );
145 
147  virtual QgsMeshVectorValueInterpolatorFromFace *clone() override;
148 
150  QgsMeshVectorValueInterpolatorFromFace &operator=( const QgsMeshVectorValueInterpolatorFromFace &other );
151 
152  private:
153  QgsVector interpolatedValuePrivate( int faceIndex, const QgsPointXY point ) const override;
154 };
155 
164 class QgsMeshStreamField
165 {
166  public:
167  struct FieldData
168  {
169  double magnitude;
170  float time;
171  int directionX;
172  int directionY;
173  };
174 
176  QgsMeshStreamField( const QgsTriangularMesh &triangularMesh,
177  const QgsMeshDataBlock &dataSetVectorValues,
178  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
179  const QgsRectangle &layerExtent,
180  double magnitudeMaximum,
181  bool dataIsOnVertices,
182  const QgsRenderContext &rendererContext,
183  int resolution = 1 );
184 
186  QgsMeshStreamField( const QgsMeshStreamField &other );
187 
189  virtual ~QgsMeshStreamField();
190 
197  void updateSize( const QgsRenderContext &renderContext );
198 
203  void updateSize( const QgsRenderContext &renderContext, int resolution );
204 
206  bool isValid() const;
207 
209  QSize size() const;
210 
212  QPoint topLeft() const;
213 
215  void addTrace( QPoint startPixel );
216 
218  void addTrace( QgsPointXY startPoint );
219 
221  void addRandomTraces();
222 
224  void addRandomTrace();
225 
227  void addGriddedTraces( int dx, int dy );
228 
230  void addTracesOnMesh( const QgsTriangularMesh &mesh, const QgsRectangle &extent );
231 
233  void setResolution( int width );
234 
236  int resolution() const;
237 
239  QSize imageSize() const;
240 
242  virtual QImage image();
243 
245  void setPixelFillingDensity( double maxFilling );
246 
248  void setColor( QColor color );
249 
251  void setLineWidth( double width );
252 
254  void setFilter( double min, double max );
255 
257  void setMinimizeFieldSize( bool minimizeFieldSize );
258 
260  QgsMeshStreamField &operator=( const QgsMeshStreamField &other );
261 
262  protected:
263  void initImage();
264  QPointF fieldToDevice( const QPoint &pixel ) const;
265  bool filterMag( double value ) const;
266 
267  private:
268  QgsPointXY positionToMapCoordinates( const QPoint &pixelPosition, const QgsPointXY &positionInPixel );
269  bool addPixelToChunkTrace( QPoint &pixel,
270  QgsMeshStreamField::FieldData &data,
271  std::list<QPair<QPoint, QgsMeshStreamField::FieldData> > &chunkTrace );
272  void setChunkTrace( std::list<QPair<QPoint, FieldData>> &chunkTrace );
273  virtual void drawChunkTrace( const std::list<QPair<QPoint, FieldData>> &chunkTrace ) = 0;
274  void clearChunkTrace( std::list<QPair<QPoint, FieldData>> &chunkTrace );
275  virtual void storeInField( const QPair<QPoint, FieldData> pixelData ) = 0;
276  virtual void initField() = 0;
277  void simplifyChunkTrace( std::list<QPair<QPoint, FieldData>> &shunkTrace );
278 
279  virtual bool isTraceExists( const QPoint &pixel ) const = 0;
280  bool isTraceOutside( const QPoint &pixel ) const;
281 
282  protected:
283 
284  QSize mFieldSize;
285  std::unique_ptr<QPainter> mPainter = std::unique_ptr<QPainter>( nullptr );
286  int mFieldResolution = 1;
287  QPen mPen;
288  QImage mTraceImage;
289 
290  QgsMapToPixel mMapToFieldPixel;
291 
292  private:
293  int mPixelFillingCount = 0;
294  int mMaxPixelFillingCount = 0;
295  std::unique_ptr<QgsMeshVectorValueInterpolator> mVectorValueInterpolator;
296  QgsRectangle mLayerExtent;
297  QgsRectangle mMapExtent;
298  QPoint mFieldTopLeftInDeviceCoordinates;
299  bool mValid = false;
300  double mMaximumMagnitude = 0;
301  double mPixelFillingDensity = 0;
302  double mMinMagFilter = -1;
303  double mMaxMagFilter = -1;
304  const QgsRenderContext &mRenderContext; //keep the renderer context only to know if the renderer is stopped
305  bool mMinimizeFieldSize = true; //
306 };
307 
316 class QgsMeshStreamlinesField: public QgsMeshStreamField
317 {
318  public:
320  QgsMeshStreamlinesField( const QgsTriangularMesh &triangularMesh,
321  const QgsMeshDataBlock &datasetVectorValues,
322  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
323  const QgsRectangle &layerExtent,
324  double magMax, bool dataIsOnVertices, QgsRenderContext &rendererContext );
325 
327  QgsMeshStreamlinesField( const QgsMeshStreamlinesField &other );
328 
330  QgsMeshStreamlinesField &operator=( const QgsMeshStreamlinesField &other );
331 
332  private:
333  void storeInField( const QPair<QPoint, FieldData> pixelData ) override;
334  void initField() override;
335  bool isTraceExists( const QPoint &pixel ) const override;
336  void drawChunkTrace( const std::list<QPair<QPoint, FieldData> > &chunkTrace ) override;
337 
338  QVector<bool> mField;
339 
340 };
341 
342 class QgsMeshParticleTracesField;
343 
352 struct QgsMeshTraceParticle
353 {
354  double lifeTime = 0;
355  QPoint position;
356  std::list<QPoint> tail;
357  double remainingTime = 0; //time remaining to spend in the current pixel at the end of the time step
358 };
359 
368 class QgsMeshParticleTracesField: public QgsMeshStreamField
369 {
370  public:
372  QgsMeshParticleTracesField( const QgsTriangularMesh &triangularMesh,
373  const QgsMeshDataBlock &datasetVectorValues,
374  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
375  const QgsRectangle &layerExtent,
376  double magMax,
377  bool dataIsOnVertices,
378  const QgsRenderContext &rendererContext );
379 
381  QgsMeshParticleTracesField( const QgsMeshParticleTracesField &other );
382 
384  void addParticle( const QPoint &startPoint, double lifeTime );
385 
387  void addParticleXY( const QgsPointXY &startPoint, double lifeTime );
388 
390  void addRandomParticles();
391 
393  void moveParticles();
394 
396  QImage imageRendered() const;
397 
399  void setParticlesCount( int particlesCount );
400 
402  void setParticlesLifeTime( double particlesLifeTime );
403 
405  void stump();
406 
412  void setStumpFactor( int sf );
413 
415  void setTimeStep( double timeStep );
416 
418  void setParticleColor( const QColor &particleColor );
419 
421  void setParticleSize( double particleSize );
422 
424  void setTailFactor( double tailFactor );
425 
427  void setMinTailLength( int minTailLength );
428 
430  QgsMeshParticleTracesField &operator=( const QgsMeshParticleTracesField &other );
431 
433  void setStumpParticleWithLifeTime( bool stumpParticleWithLifeTime );
434 
435  private:
436  QPoint direction( QPoint position ) const;
437 
438  float time( QPoint position ) const;
439 
440  void drawParticleTrace( const QgsMeshTraceParticle &particle );
441 
442  void storeInField( const QPair<QPoint, FieldData> pixelData ) override;
443  void initField() override;
444  bool isTraceExists( const QPoint &pixel ) const override;
445  void drawChunkTrace( const std::list<QPair<QPoint, FieldData>> &chunkTrace ) override {Q_UNUSED( chunkTrace );}
446 
447  /* Nondimensional time
448  * This field store the time spent by the particle in the pixel
449  *
450  * This time is nondimensional and value 1 is equivalent to the time spent by the particle in a pixel
451  * for Vmax, the maximum magnitude of the vector field.
452  *
453  */
454  QVector<float> mTimeField;
455 
456  /*the direction for a pixel is defined with a char value
457  *
458  * 1 2 3
459  * 4 5 6
460  * 7 8 9
461  *
462  * convenient to retrieve the indexes of the next pixel from the direction d:
463  * Xnext= (d-1)%3-1
464  * Ynext = (d-1)/3-1
465  *
466  * and the direction is defined by :
467  * d=incX + 2 + (incY+1)*3
468  */
469  QVector<char> mDirectionField;
470  QList<QgsMeshTraceParticle> mParticles;
471  QImage mStumpImage;
472 
473  double mTimeStep = 200;
474  double mParticlesLifeTime = 5000;
475  int mParticlesCount = 1000;
476  double mTailFactor = 5;
477  int mMinTailLength = 3;
478  QColor mParticleColor = Qt::white;
479  double mParticleSize = 2.5;
480  int mStumpFactor = 50;
481  bool mStumpParticleWithLifeTime = true;
482 };
483 
492 class QgsMeshVectorStreamlineRenderer: public QgsMeshVectorRenderer
493 {
494  public:
496  QgsMeshVectorStreamlineRenderer( const QgsTriangularMesh &triangularMesh,
497  const QgsMeshDataBlock &dataSetVectorValues,
498  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
499  bool dataIsOnVertices,
500  const QgsMeshRendererVectorSettings &settings,
501  QgsRenderContext &rendererContext,
502  const QgsRectangle &layerExtent,
503  double magMax );
504 
505  void draw() override;
506 
507  private:
508  std::unique_ptr<QgsMeshStreamField> mStreamlineField;
509  QgsRenderContext &mRendererContext;
510 };
511 
512 
521 class QgsMeshVectorTraceRenderer: public QgsMeshVectorRenderer
522 {
523  public:
525  QgsMeshVectorTraceRenderer( const QgsTriangularMesh &triangularMesh,
526  const QgsMeshDataBlock &dataSetVectorValues,
527  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
528  bool dataIsOnVertices,
529  const QgsMeshRendererVectorSettings &settings,
530  QgsRenderContext &rendererContext,
531  const QgsRectangle &layerExtent,
532  double magMax );
533 
534  void draw() override;
535 
536  private:
537  std::unique_ptr<QgsMeshParticleTracesField> mParticleField;
538  QgsRenderContext &mRendererContext;
539 };
540 
541 
542 #endif //SIP_RUN
543 
545 
554 {
555  public:
558  const QgsMeshDataBlock &dataSetVectorValues,
559  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
560  bool dataIsOnVertices,
561  const QgsRenderContext &rendererContext,
562  const QgsRectangle &layerExtent,
563  double magMax ) SIP_SKIP;
564 
566  QgsMeshVectorTraceAnimationGenerator( QgsMeshLayer *layer, const QgsRenderContext &rendererContext );
567 
570 
573 
575  void seedRandomParticles( int count );
576 
578  QImage imageRendered();
579 
581  void setFPS( int FPS );
582 
584  void setMaxSpeedPixel( int max );
585 
587  void setParticlesLifeTime( double particleLifeTime );
588 
590  void setParticlesColor( const QColor &c );
591 
593  void setParticlesSize( double width );
594 
596  void setTailFactor( double fct );
597 
599  void setMinimumTailLength( int l );
600 
602  void setTailPersitence( double p );
603 
606  private:
607  std::unique_ptr<QgsMeshParticleTracesField> mParticleField;
608  const QgsRenderContext &mRendererContext;
609  int mFPS = 15; //frame per second of the output, used to calculate orher parameters of the field
610  int mVpixMax = 2000; //is the number of pixels that are going through for 1 s
611  double mParticleLifeTime = 5;
612 
613  void updateFieldParameter();
614 };
615 
616 #endif // QGSMESHTRACERENDERER_H
A rectangle specified with double values.
Definition: qgsrectangle.h:41
Triangular/Derived Mesh is mesh with vertices in map coordinates.
A class to represent a 2D point.
Definition: qgspointxy.h:43
QgsMeshDataBlock is a block of integers/doubles that can be used to retrieve: active flags (e...
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
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:37
A wrapper for QgsMeshParticuleTracesField used to render the particles.
Represents a streamline renderer settings for vector datasets.
#define SIP_SKIP
Definition: qgis_sip.h:126
A class to represent a vector.
Definition: qgsvector.h:29
Contains information about the context of a rendering operation.
QVector< int > QgsMeshFace
List of vertex indexes.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:91