QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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 
66  virtual QgsVector vectorValue( const QgsPointXY &point ) const;
67 
69  QgsMeshVectorValueInterpolator &operator=( const QgsMeshVectorValueInterpolator &other );
70 
71  protected:
72  void updateCacheFaceIndex( const QgsPointXY &point ) const;
73 
74  QgsTriangularMesh mTriangularMesh;
75  QgsMeshDataBlock mDatasetValues;
76  QgsMeshDataBlock mActiveFaceFlagValues;
77  mutable QgsMeshFace mFaceCache;
78  mutable int mCacheFaceIndex = -1;
79  bool mUseScalarActiveFaceFlagValues = false;
80  bool isVectorValid( const QgsVector &v ) const;
81 
82  private:
83 
84  void activeFaceFilter( QgsVector &vector, int faceIndex ) const;
85 
86  virtual QgsVector interpolatedValuePrivate( int faceIndex, const QgsPointXY point ) const = 0;
87 };
88 
97 class QgsMeshVectorValueInterpolatorFromVertex: public QgsMeshVectorValueInterpolator
98 {
99  public:
101  QgsMeshVectorValueInterpolatorFromVertex( const QgsTriangularMesh &triangularMesh,
102  const QgsMeshDataBlock &datasetVectorValues );
103 
105  QgsMeshVectorValueInterpolatorFromVertex( const QgsTriangularMesh &triangularMesh,
106  const QgsMeshDataBlock &datasetVectorValues,
107  const QgsMeshDataBlock &scalarActiveFaceFlagValues );
108 
110  QgsMeshVectorValueInterpolatorFromVertex( const QgsMeshVectorValueInterpolatorFromVertex &other );
111 
113  virtual QgsMeshVectorValueInterpolatorFromVertex *clone() override;
114 
116  QgsMeshVectorValueInterpolatorFromVertex &operator=( const QgsMeshVectorValueInterpolatorFromVertex &other );
117 
118  private:
119  QgsVector interpolatedValuePrivate( int faceIndex, const QgsPointXY point ) const override;
120 };
121 
130 class QgsMeshVectorValueInterpolatorFromFace: public QgsMeshVectorValueInterpolator
131 {
132  public:
134  QgsMeshVectorValueInterpolatorFromFace( const QgsTriangularMesh &triangularMesh,
135  const QgsMeshDataBlock &datasetVectorValues );
136 
138  QgsMeshVectorValueInterpolatorFromFace( const QgsTriangularMesh &triangularMesh,
139  const QgsMeshDataBlock &datasetVectorValues,
140  const QgsMeshDataBlock &scalarActiveFaceFlagValues );
141 
143  QgsMeshVectorValueInterpolatorFromFace( const QgsMeshVectorValueInterpolatorFromFace &other );
144 
146  virtual QgsMeshVectorValueInterpolatorFromFace *clone() override;
147 
149  QgsMeshVectorValueInterpolatorFromFace &operator=( const QgsMeshVectorValueInterpolatorFromFace &other );
150 
151  private:
152  QgsVector interpolatedValuePrivate( int faceIndex, const QgsPointXY point ) const override;
153 };
154 
163 class QgsMeshStreamField
164 {
165  public:
166  struct FieldData
167  {
168  double magnitude;
169  float time;
170  int directionX;
171  int directionY;
172  };
173 
175  QgsMeshStreamField( const QgsTriangularMesh &triangularMesh,
176  const QgsMeshDataBlock &dataSetVectorValues,
177  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
178  const QgsRectangle &layerExtent,
179  double magnitudeMaximum,
180  bool dataIsOnVertices,
181  const QgsRenderContext &rendererContext,
182  const QgsInterpolatedLineColor &vectorColoring,
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  QgsInterpolatedLineColor mVectorColoring;
292 
293  private:
294  int mPixelFillingCount = 0;
295  int mMaxPixelFillingCount = 0;
296  std::unique_ptr<QgsMeshVectorValueInterpolator> mVectorValueInterpolator;
297  QgsRectangle mLayerExtent;
298  QgsRectangle mMapExtent;
299  QPoint mFieldTopLeftInDeviceCoordinates;
300  bool mValid = false;
301  double mMaximumMagnitude = 0;
302  double mPixelFillingDensity = 0;
303  double mMinMagFilter = -1;
304  double mMaxMagFilter = -1;
305  const QgsRenderContext &mRenderContext; //keep the renderer context only to know if the renderer is stopped
306  bool mMinimizeFieldSize = true; //
307 };
308 
317 class QgsMeshStreamlinesField: public QgsMeshStreamField
318 {
319  public:
321  QgsMeshStreamlinesField( const QgsTriangularMesh &triangularMesh,
322  const QgsMeshDataBlock &datasetVectorValues,
323  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
324  const QgsRectangle &layerExtent,
325  double magMax,
326  bool dataIsOnVertices,
327  QgsRenderContext &rendererContext,
328  const QgsInterpolatedLineColor vectorColoring );
329 
331  QgsMeshStreamlinesField( const QgsMeshStreamlinesField &other );
332 
334  QgsMeshStreamlinesField &operator=( const QgsMeshStreamlinesField &other );
335 
336  private:
337  void storeInField( const QPair<QPoint, FieldData> pixelData ) override;
338  void initField() override;
339  bool isTraceExists( const QPoint &pixel ) const override;
340  void drawChunkTrace( const std::list<QPair<QPoint, FieldData> > &chunkTrace ) override;
341 
342  QVector<bool> mField;
343 
344 };
345 
346 class QgsMeshParticleTracesField;
347 
356 struct QgsMeshTraceParticle
357 {
358  double lifeTime = 0;
359  QPoint position;
360  std::list<QPoint> tail;
361  double remainingTime = 0; //time remaining to spend in the current pixel at the end of the time step
362 };
363 
372 class QgsMeshParticleTracesField: public QgsMeshStreamField
373 {
374  public:
376  QgsMeshParticleTracesField( const QgsTriangularMesh &triangularMesh,
377  const QgsMeshDataBlock &datasetVectorValues,
378  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
379  const QgsRectangle &layerExtent,
380  double magMax,
381  bool dataIsOnVertices,
382  const QgsRenderContext &rendererContext,
383  const QgsInterpolatedLineColor vectorColoring );
384 
386  QgsMeshParticleTracesField( const QgsMeshParticleTracesField &other );
387 
389  void addParticle( const QPoint &startPoint, double lifeTime );
390 
392  void addParticleXY( const QgsPointXY &startPoint, double lifeTime );
393 
395  void addRandomParticles();
396 
398  void moveParticles();
399 
401  QImage imageRendered() const;
402 
404  void setParticlesCount( int particlesCount );
405 
407  void setParticlesLifeTime( double particlesLifeTime );
408 
410  void stump();
411 
417  void setStumpFactor( int sf );
418 
420  void setTimeStep( double timeStep );
421 
423  void setParticleSize( double particleSize );
424 
426  void setTailFactor( double tailFactor );
427 
429  void setMinTailLength( int minTailLength );
430 
432  QgsMeshParticleTracesField &operator=( const QgsMeshParticleTracesField &other );
433 
435  void setStumpParticleWithLifeTime( bool stumpParticleWithLifeTime );
436 
438  void setParticlesColor( const QColor &c );
439  private:
440  QPoint direction( QPoint position ) const;
441 
442  float time( QPoint position ) const;
443  float magnitude( QPoint position ) const;
444 
445  void drawParticleTrace( const QgsMeshTraceParticle &particle );
446 
447  void storeInField( const QPair<QPoint, FieldData> pixelData ) override;
448  void initField() override;
449  bool isTraceExists( const QPoint &pixel ) const override;
450  void drawChunkTrace( const std::list<QPair<QPoint, FieldData>> &chunkTrace ) override {Q_UNUSED( chunkTrace )}
451 
452  /* Nondimensional time
453  * This field store the time spent by the particle in the pixel
454  *
455  * This time is nondimensional and value 1 is equivalent to the time spent by the particle in a pixel
456  * for Vmax, the maximum magnitude of the vector field.
457  *
458  */
459  QVector<float> mTimeField;
460  QVector<float> mMagnitudeField;
461 
462  /*the direction for a pixel is defined with a char value
463  *
464  * 1 2 3
465  * 4 5 6
466  * 7 8 9
467  *
468  * convenient to retrieve the indexes of the next pixel from the direction d:
469  * Xnext= (d-1)%3-1
470  * Ynext = (d-1)/3-1
471  *
472  * and the direction is defined by :
473  * d=incX + 2 + (incY+1)*3
474  */
475  QVector<char> mDirectionField;
476  QList<QgsMeshTraceParticle> mParticles;
477  QImage mStumpImage;
478 
479  double mTimeStep = 200;
480  double mParticlesLifeTime = 5000;
481  int mParticlesCount = 1000;
482  double mTailFactor = 5;
483  int mMinTailLength = 3;
484  QColor mParticleColor = Qt::white;
485  double mParticleSize = 2.5;
486  int mStumpFactor = 50;
487  bool mStumpParticleWithLifeTime = true;
488 };
489 
500 class QgsMeshVectorStreamlineRenderer: public QgsMeshVectorRenderer
501 {
502  public:
504  QgsMeshVectorStreamlineRenderer( const QgsTriangularMesh &triangularMesh,
505  const QgsMeshDataBlock &dataSetVectorValues,
506  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
507  bool dataIsOnVertices,
508  const QgsMeshRendererVectorSettings &settings,
509  QgsRenderContext &rendererContext,
510  const QgsRectangle &layerExtent,
511  double magMax );
512 
513  void draw() override;
514 
515  private:
516  std::unique_ptr<QgsMeshStreamField> mStreamlineField;
517  QgsRenderContext &mRendererContext;
518 };
519 
520 
531 class QgsMeshVectorTraceRenderer: public QgsMeshVectorRenderer
532 {
533  public:
535  QgsMeshVectorTraceRenderer( const QgsTriangularMesh &triangularMesh,
536  const QgsMeshDataBlock &dataSetVectorValues,
537  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
538  bool dataIsOnVertices,
539  const QgsMeshRendererVectorSettings &settings,
540  QgsRenderContext &rendererContext,
541  const QgsRectangle &layerExtent,
542  double magMax );
543 
544  void draw() override;
545 
546  private:
547  std::unique_ptr<QgsMeshParticleTracesField> mParticleField;
548  QgsRenderContext &mRendererContext;
549 };
550 
551 
552 #endif //SIP_RUN
553 
555 
564 {
565  public:
568  const QgsMeshDataBlock &dataSetVectorValues,
569  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
570  bool dataIsOnVertices,
571  const QgsRenderContext &rendererContext,
572  const QgsRectangle &layerExtent,
573  double magMax,
574  const QgsMeshRendererVectorSettings &vectorSettings ) SIP_SKIP;
575 
577  QgsMeshVectorTraceAnimationGenerator( QgsMeshLayer *layer, const QgsRenderContext &rendererContext );
578 
581 
584 
586  void seedRandomParticles( int count );
587 
589  QImage imageRendered();
590 
592  void setFPS( int FPS );
593 
595  void setMaxSpeedPixel( int max );
596 
598  void setParticlesLifeTime( double particleLifeTime );
599 
601  void setParticlesColor( const QColor &c );
602 
604  void setParticlesSize( double width );
605 
607  void setTailFactor( double fct );
608 
610  void setMinimumTailLength( int l );
611 
613  void setTailPersitence( double p );
614 
617  private:
618  std::unique_ptr<QgsMeshParticleTracesField> mParticleField;
619  const QgsRenderContext &mRendererContext;
620  int mFPS = 15; //frame per second of the output, used to calculate orher parameters of the field
621  int mVpixMax = 2000; //is the number of pixels that are going through for 1 s
622  double mParticleLifeTime = 5;
623 
624  void updateFieldParameter();
625 };
626 
627 #endif // QGSMESHTRACERENDERER_H
qgsmeshlayerutils.h
QgsMeshRendererVectorSettings
Definition: qgsmeshrenderersettings.h:410
qgis.h
QgsRenderContext
Definition: qgsrendercontext.h:57
QgsMeshVectorTraceAnimationGenerator
Definition: qgsmeshtracerenderer.h:563
QgsRectangle
Definition: qgsrectangle.h:41
qgstriangularmesh.h
SIP_SKIP
#define SIP_SKIP
Definition: qgis_sip.h:126
QgsMeshLayer
Definition: qgsmeshlayer.h:94
QgsInterpolatedLineColor
Definition: qgsinterpolatedlinerenderer.h:34
QgsMeshFace
QVector< int > QgsMeshFace
List of vertex indexes.
Definition: qgsmeshdataprovider.h:41
qgsmeshlayer.h
QgsPointXY
Definition: qgspointxy.h:43
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
Definition: qgsmaptopixel.h:37
qgsmeshvectorrenderer.h
QgsVector
Definition: qgsvector.h:29
QgsMeshDataBlock
Definition: qgsmeshdataset.h:134
QgsTriangularMesh
Definition: qgstriangularmesh.h:49