Branch data Line data Source code
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 : : ///@cond PRIVATE
33 : :
34 : : #ifndef SIP_RUN
35 : :
36 : : /**
37 : : * \ingroup core
38 : : *
39 : : * \brief Abstract class used to interpolate the value of the vector for a pixel
40 : : *
41 : : * \note not available in Python bindings
42 : : * \since QGIS 3.12
43 : : */
44 : : class QgsMeshVectorValueInterpolator
45 : : {
46 : : public:
47 : : //! Constructor
48 : : QgsMeshVectorValueInterpolator( const QgsTriangularMesh &triangularMesh,
49 : : const QgsMeshDataBlock &datasetVectorValues );
50 : :
51 : : //! Constructor with scalar active face flag values to not interpolate on inactive face
52 : : QgsMeshVectorValueInterpolator( const QgsTriangularMesh &triangularMesh,
53 : : const QgsMeshDataBlock &datasetVectorValues,
54 : : const QgsMeshDataBlock &scalarActiveFaceFlagValues );
55 : :
56 : : //! Copy constructor
57 : : QgsMeshVectorValueInterpolator( const QgsMeshVectorValueInterpolator &other );
58 : :
59 : : //! Clone
60 : : virtual QgsMeshVectorValueInterpolator *clone() = 0;
61 : :
62 : : //! Destructor
63 : 0 : virtual ~QgsMeshVectorValueInterpolator() = default;
64 : :
65 : : /**
66 : : * Returns the interpolated vector
67 : : * \param point point in map coordinates
68 : : */
69 : : virtual QgsVector vectorValue( const QgsPointXY &point ) const;
70 : :
71 : : //! Assignment operator
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 : :
92 : : /**
93 : : * \ingroup core
94 : : *
95 : : * \brief Class used to retrieve the value of the vector for a pixel from vertex
96 : : *
97 : : * \note not available in Python bindings
98 : : * \since QGIS 3.12
99 : : */
100 : 0 : class QgsMeshVectorValueInterpolatorFromVertex: public QgsMeshVectorValueInterpolator
101 : : {
102 : : public:
103 : : //! Constructor
104 : : QgsMeshVectorValueInterpolatorFromVertex( const QgsTriangularMesh &triangularMesh,
105 : : const QgsMeshDataBlock &datasetVectorValues );
106 : :
107 : : //! Constructor with scalar active face flag value to not interpolate on inactive face
108 : : QgsMeshVectorValueInterpolatorFromVertex( const QgsTriangularMesh &triangularMesh,
109 : : const QgsMeshDataBlock &datasetVectorValues,
110 : : const QgsMeshDataBlock &scalarActiveFaceFlagValues );
111 : :
112 : : //! Copy constructor
113 : : QgsMeshVectorValueInterpolatorFromVertex( const QgsMeshVectorValueInterpolatorFromVertex &other );
114 : :
115 : : //! Clone the instance
116 : : virtual QgsMeshVectorValueInterpolatorFromVertex *clone() override;
117 : :
118 : : //! Assignment operator
119 : : QgsMeshVectorValueInterpolatorFromVertex &operator=( const QgsMeshVectorValueInterpolatorFromVertex &other );
120 : :
121 : : private:
122 : : QgsVector interpolatedValuePrivate( int faceIndex, const QgsPointXY point ) const override;
123 : : };
124 : :
125 : : /**
126 : : * \ingroup core
127 : : *
128 : : * \brief Class used to retrieve the value of the vector for a pixel from vertex
129 : : *
130 : : * \note not available in Python bindings
131 : : * \since QGIS 3.12
132 : : */
133 : 0 : class QgsMeshVectorValueInterpolatorFromFace: public QgsMeshVectorValueInterpolator
134 : : {
135 : : public:
136 : : //! Constructor
137 : : QgsMeshVectorValueInterpolatorFromFace( const QgsTriangularMesh &triangularMesh,
138 : : const QgsMeshDataBlock &datasetVectorValues );
139 : :
140 : : //! Constructor with scalar active face flag value to not interpolate on inactive face
141 : : QgsMeshVectorValueInterpolatorFromFace( const QgsTriangularMesh &triangularMesh,
142 : : const QgsMeshDataBlock &datasetVectorValues,
143 : : const QgsMeshDataBlock &scalarActiveFaceFlagValues );
144 : :
145 : : //! Copy constructor
146 : : QgsMeshVectorValueInterpolatorFromFace( const QgsMeshVectorValueInterpolatorFromFace &other );
147 : :
148 : : //! Clone the instance
149 : : virtual QgsMeshVectorValueInterpolatorFromFace *clone() override;
150 : :
151 : : //! Assignment operator
152 : : QgsMeshVectorValueInterpolatorFromFace &operator=( const QgsMeshVectorValueInterpolatorFromFace &other );
153 : :
154 : : private:
155 : : QgsVector interpolatedValuePrivate( int faceIndex, const QgsPointXY point ) const override;
156 : : };
157 : :
158 : : /**
159 : : * \ingroup core
160 : : *
161 : : * \brief Abstract class used to handle information about stream field
162 : : *
163 : : * \note not available in Python bindings
164 : : * \since QGIS 3.12
165 : : */
166 : : class QgsMeshStreamField
167 : : {
168 : : public:
169 : : struct FieldData
170 : : {
171 : : double magnitude;
172 : : float time;
173 : : int directionX;
174 : : int directionY;
175 : : };
176 : :
177 : : //! Constructor
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 : :
188 : : //! Copy constructor
189 : : QgsMeshStreamField( const QgsMeshStreamField &other );
190 : :
191 : : //! Destructor
192 : : virtual ~QgsMeshStreamField();
193 : :
194 : : /**
195 : : * Updates the size of the field and the QgsMapToPixel instance to retrieve map point
196 : : * from pixel in the field depending on the resolution of the device
197 : : * If the extent of renderer context and the resolution are not changed, do nothing
198 : : * else, updates the size and cleans
199 : : */
200 : : void updateSize( const QgsRenderContext &renderContext );
201 : :
202 : : /**
203 : : * Updates the size of the field and the QgsMapToPixel instance to retrieve map point
204 : : * from pixel in the field depending on the resolution of the device
205 : : */
206 : : void updateSize( const QgsRenderContext &renderContext, int resolution );
207 : :
208 : : //! Returns true if the field is valid
209 : : bool isValid() const;
210 : :
211 : : //! Returns the size of the field
212 : : QSize size() const;
213 : :
214 : : //! Returns the topLeft of the field in the device coordinate
215 : : QPoint topLeft() const;
216 : :
217 : : //! Adds a trace in the field from a start pixel
218 : : void addTrace( QPoint startPixel );
219 : :
220 : : //! Adds a trace in the field from a map point
221 : : void addTrace( QgsPointXY startPoint );
222 : :
223 : : //! Adds random traces in the field from random start points, the number of traces depends on the max filling density
224 : : void addRandomTraces();
225 : :
226 : : //! Adds a trace in the field from one random start point
227 : : void addRandomTrace();
228 : :
229 : : //! Adds traces in the field from gridded start points, pixelSpace is the space between points in pixel field
230 : : void addGriddedTraces( int dx, int dy );
231 : :
232 : : //! Adds traces in the field from vertex on a mesh
233 : : void addTracesOnMesh( const QgsTriangularMesh &mesh, const QgsRectangle &extent );
234 : :
235 : : //! Sets the resolution of the field
236 : : void setResolution( int width );
237 : :
238 : : //! Returns the width of particle
239 : : int resolution() const;
240 : :
241 : : //! Returns the size of the image that represents the trace field
242 : : QSize imageSize() const;
243 : :
244 : : //! Returns the current render image of the field
245 : : virtual QImage image();
246 : :
247 : : //! Sets the maximum pixel filling, eg, the rate of number pixel that can be filled with way.
248 : : void setPixelFillingDensity( double maxFilling );
249 : :
250 : : //! Sets color of the streamlines
251 : : void setColor( QColor color );
252 : :
253 : : //! Sets line width of the streamlines (in px)
254 : : void setLineWidth( double width );
255 : :
256 : : //! Sets min/max filter
257 : : void setFilter( double min, double max );
258 : :
259 : : //! Sets if the size of the field has to be minimized of all the mesh is in the device
260 : : void setMinimizeFieldSize( bool minimizeFieldSize );
261 : :
262 : : //! Assignment operator
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 : :
312 : : /**
313 : : * \ingroup core
314 : : *
315 : : * \brief Class used to draw streamlines from vector field
316 : : *
317 : : * \note not available in Python bindings
318 : : * \since QGIS 3.12
319 : : */
320 : 0 : class QgsMeshStreamlinesField: public QgsMeshStreamField
321 : : {
322 : : public:
323 : : //! Constructor
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 : :
333 : : //! Copy constructor
334 : : QgsMeshStreamlinesField( const QgsMeshStreamlinesField &other );
335 : :
336 : : //! Assignment operator
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 : :
351 : : /**
352 : : * \ingroup core
353 : : *
354 : : * \brief Used to simulation moving particle
355 : : *
356 : : * \note not available in Python bindings
357 : : * \since QGIS 3.12
358 : : */
359 : 0 : struct QgsMeshTraceParticle
360 : : {
361 : 0 : double lifeTime = 0;
362 : : QPoint position;
363 : : std::list<QPoint> tail;
364 : 0 : double remainingTime = 0; //time remaining to spend in the current pixel at the end of the time step
365 : : };
366 : :
367 : : /**
368 : : * \ingroup core
369 : : *
370 : : * \brief Class used to draw streamlines from vector field
371 : : *
372 : : * \note not available in Python bindings
373 : : * \since QGIS 3.12
374 : : */
375 : 0 : class QgsMeshParticleTracesField: public QgsMeshStreamField
376 : : {
377 : : public:
378 : : //! Constructor
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 : :
388 : : //! Copy constructor
389 : : QgsMeshParticleTracesField( const QgsMeshParticleTracesField &other );
390 : :
391 : : //! Adds a particle in the vector field from a start point (pixel) with a specified life time
392 : : void addParticle( const QPoint &startPoint, double lifeTime );
393 : :
394 : : //! Adds a particle in the vector field from a start point (map point) with a specified life time
395 : : void addParticleXY( const QgsPointXY &startPoint, double lifeTime );
396 : :
397 : : //! Adds particle randomly (position and life time
398 : : void addRandomParticles();
399 : :
400 : : //! Moves all the particles with a displacement corresponding to a nondimensional time
401 : : void moveParticles();
402 : :
403 : : //! Returns the current image of the particles
404 : : QImage imageRendered() const;
405 : :
406 : : //! Sets the total number of particles generated randomly
407 : : void setParticlesCount( int particlesCount );
408 : :
409 : : //! Sets the maximum life time (nondimensional) of particle generated
410 : : void setParticlesLifeTime( double particlesLifeTime );
411 : :
412 : : //! Stumps particles image and leave a persistent effect
413 : : void stump();
414 : :
415 : : /**
416 : : * Sets stump factor from 0 to 255 :
417 : : * 0, stump completely, no persistence
418 : : * 255, no stump, total persistence
419 : : */
420 : : void setStumpFactor( int sf );
421 : :
422 : : //! Sets the time step
423 : : void setTimeStep( double timeStep );
424 : :
425 : : //! Sets particles size (in px)
426 : : void setParticleSize( double particleSize );
427 : :
428 : : //! Sets the tail factor
429 : : void setTailFactor( double tailFactor );
430 : :
431 : : //! Sets the minimum tail length
432 : : void setMinTailLength( int minTailLength );
433 : :
434 : : //! Assignment operator
435 : : QgsMeshParticleTracesField &operator=( const QgsMeshParticleTracesField &other );
436 : :
437 : : //! Sets if the particle has to be stumped dependiong on liketime
438 : : void setStumpParticleWithLifeTime( bool stumpParticleWithLifeTime );
439 : :
440 : : //! Sets the color of the particles, overwrite the color provided by vector settings
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 : 0 : 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 : :
493 : : /**
494 : : * \ingroup core
495 : : *
496 : : * \brief A class derived from QgsMeshVectorRenderer used to render the particles traces
497 : : *
498 : : * Not available for data defined on edges
499 : : *
500 : : * \note not available in Python bindings
501 : : * \since QGIS 3.12
502 : : */
503 : 0 : class QgsMeshVectorStreamlineRenderer: public QgsMeshVectorRenderer
504 : : {
505 : : public:
506 : : //!Constructor
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 : :
524 : : /**
525 : : * \ingroup core
526 : : *
527 : : * \brief A class derived from QgsMeshVectorRenderer used to render the particles traces.
528 : : *
529 : : * Not available for data defined on edges
530 : : *
531 : : * \note not available in Python bindings
532 : : * \since QGIS 3.12
533 : : */
534 : 0 : class QgsMeshVectorTraceRenderer: public QgsMeshVectorRenderer
535 : : {
536 : : public:
537 : : //!Constructor
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 : :
557 : : ///@endcond
558 : :
559 : : /**
560 : : * \ingroup core
561 : : *
562 : : * \brief A wrapper for QgsMeshParticuleTracesField used to render the particles. Available for Python binding
563 : : *
564 : : * \since QGIS 3.12
565 : : */
566 : : class CORE_EXPORT QgsMeshVectorTraceAnimationGenerator
567 : : {
568 : : public:
569 : : //!Constructor to use from QgsMeshVectorRenderer
570 : : QgsMeshVectorTraceAnimationGenerator( const QgsTriangularMesh &triangularMesh,
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 : :
579 : : //!Constructor to use with Python binding
580 : : QgsMeshVectorTraceAnimationGenerator( QgsMeshLayer *layer, const QgsRenderContext &rendererContext );
581 : :
582 : : //! Copy constructor
583 : : QgsMeshVectorTraceAnimationGenerator( const QgsMeshVectorTraceAnimationGenerator &other );
584 : :
585 : : //! Destructor
586 : : ~QgsMeshVectorTraceAnimationGenerator() = default;
587 : :
588 : : //! seeds particles in the vector fields
589 : : void seedRandomParticles( int count );
590 : :
591 : : //! Moves all the particles using frame per second (fps) to calculate the displacement and return the rendered frame
592 : : QImage imageRendered();
593 : :
594 : : //! Sets the number of frames per seconds that will be rendered
595 : : void setFPS( int FPS );
596 : :
597 : : //! Sets the max number of pixels that can be go through by the particles in 1 second
598 : : void setMaxSpeedPixel( int max );
599 : :
600 : : //! Sets maximum life time of particles in seconds
601 : : void setParticlesLifeTime( double particleLifeTime );
602 : :
603 : : //! Sets colors of particle
604 : : void setParticlesColor( const QColor &c );
605 : :
606 : : //! Sets particle size in px
607 : : void setParticlesSize( double width );
608 : :
609 : : //! Sets the tail factor, used to adjust the length of the tail. 0 : minimum length, >1 increase the tail
610 : : void setTailFactor( double fct );
611 : :
612 : : //! Sets the minimum tail length
613 : : void setMinimumTailLength( int l );
614 : :
615 : : //! Sets the visual persistence of the tail
616 : : void setTailPersitence( double p );
617 : :
618 : : //! Assignment operator
619 : : QgsMeshVectorTraceAnimationGenerator &operator=( const QgsMeshVectorTraceAnimationGenerator &other );
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
|