QGIS API Documentation 4.3.0-Master (16649ce5cc6)
Loading...
Searching...
No Matches
qgsvectorfieldtraceanimationgenerator.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsvectorfieldtraceanimationgenerator.cpp
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
19
20#include "qgsmeshlayer.h"
22#include "qgsmeshlayerutils.h"
27
29 std::unique_ptr<QgsVectorFieldValueSource> source, const QgsRenderContext &rendererContext, const QgsVectorFieldSettings &vectorSettings, bool minimizeFieldSize
30)
31 : mParticleField( std::make_unique<QgsVectorFieldParticleTracesField>( std::move( source ), rendererContext, vectorSettings.vectorStrokeColoring() ) )
32 , mRendererContext( rendererContext )
33{
34 mParticleField->setMinimizeFieldSize( minimizeFieldSize );
35 mParticleField->updateSize( mRendererContext );
36}
37
39{
40 if ( !layer || !layer->dataProvider() )
41 return nullptr;
42
43 if ( !layer->triangularMesh() )
44 layer->reload();
45
46 if ( !layer->triangularMesh() || !layer->nativeMesh() )
47 return nullptr;
48
49 return new QgsVectorFieldTraceAnimationGenerator( layer, rendererContext );
50}
52 : mRendererContext( rendererContext )
53{
54 QgsMeshDataBlock vectorDatasetValues;
55 QgsMeshDataBlock scalarActiveFaceFlagValues;
56 QVector<double> magnitudeValues;
57 bool vectorDataOnVertices;
58 double magMax;
59
60 const QgsMeshDatasetIndex datasetIndex = layer->activeVectorDatasetAtTime( rendererContext.temporalRange() );
61
62 // Find out if we can use cache up to date. If yes, use it and return
63 const int datasetGroupCount = layer->dataProvider()->datasetGroupCount();
64 const QgsVectorFieldSettings vectorSettings = layer->rendererSettings().vectorSettings( datasetIndex.group() );
65 const QgsMeshLayerRendererCache *cache = layer->rendererCache();
66
67 if ( cache && ( cache->mDatasetGroupsCount == datasetGroupCount ) && ( cache->mActiveVectorDatasetIndex == datasetIndex ) )
68 {
69 vectorDatasetValues = cache->mVectorDatasetValues;
70 scalarActiveFaceFlagValues = cache->mScalarActiveFaceFlagValues;
71 magnitudeValues = cache->mVectorDatasetValuesMag;
72 magMax = cache->mVectorDatasetMagMaximum;
73 vectorDataOnVertices = cache->mVectorDataType == QgsMeshDatasetGroupMetadata::DataOnVertices;
74 }
75 else
76 {
77 const QgsMeshDatasetGroupMetadata metadata = layer->dataProvider()->datasetGroupMetadata( datasetIndex.group() );
78 magMax = metadata.maximum();
79 vectorDataOnVertices = metadata.dataType() == QgsMeshDatasetGroupMetadata::DataOnVertices;
80
81 int count;
82 if ( vectorDataOnVertices )
83 count = layer->nativeMesh()->vertices.count();
84 else
85 count = layer->nativeMesh()->faces.count();
86
87 vectorDatasetValues = QgsMeshLayerUtils::datasetValues( layer, datasetIndex, 0, count );
88 scalarActiveFaceFlagValues = layer->dataProvider()->areFacesActive( datasetIndex, 0, layer->nativeMesh()->faces.count() );
89 magnitudeValues = QgsMeshLayerUtils::calculateMagnitudes( vectorDatasetValues );
90 }
91
92 mParticleField = std::make_unique<QgsVectorFieldParticleTracesField>(
93 QgsMeshVectorFieldValueSource::create(
94 *layer->triangularMesh(),
95 vectorDatasetValues,
96 scalarActiveFaceFlagValues,
97 magnitudeValues,
99 layer->extent(),
100 magMax
101 ),
102 rendererContext,
103 vectorSettings.vectorStrokeColoring()
104 );
105
106 // the whole layer is animated, not only the part of it which is currently on the device
107 mParticleField->setMinimizeFieldSize( false );
108 mParticleField->updateSize( mRendererContext );
109}
110
112 : mParticleField( std::make_unique<QgsVectorFieldParticleTracesField>( *other.mParticleField ) )
113 , mRendererContext( other.mRendererContext )
114 , mFps( other.mFps )
115 , mVpixMax( other.mVpixMax )
116 , mParticleLifeTime( other.mParticleLifeTime )
117{}
118
120
122{
123 mParticleField->setParticlesCount( count );
124 mParticleField->addRandomParticles();
125}
126
128{
129 mParticleField->moveParticles();
130 return mParticleField->image();
131}
132
134{
135 if ( frames > 0 )
136 mFps = frames;
137 else
138 mFps = 1;
139
140 updateFieldParameter();
141}
142
144{
145 mVpixMax = pixels;
146 updateFieldParameter();
147}
148
150{
151 mParticleLifeTime = particleLifeTime;
152 updateFieldParameter();
153}
154
156{
157 mParticleField->setParticlesColor( c );
158}
159
161{
162 mParticleField->setParticleSize( width );
163}
164
166{
167 mParticleField->setTailFactor( fct );
168}
169
171{
172 mParticleField->setMinTailLength( l );
173}
174
176{
177 if ( p < 0 )
178 p = 0;
179 if ( p > 1 )
180 p = 1;
181 mParticleField->setStumpFactor( int( 255 * p ) );
182}
183
185{
186 mParticleField = std::make_unique<QgsVectorFieldParticleTracesField>( *( other.mParticleField ) );
187 const_cast<QgsRenderContext &>( mRendererContext ) = other.mRendererContext;
188 mFps = other.mFps;
189 mVpixMax = other.mVpixMax;
190 mParticleLifeTime = other.mParticleLifeTime;
191
192 return ( *this );
193}
194
195void QgsVectorFieldTraceAnimationGenerator::updateFieldParameter()
196{
197 const double fieldTimeStep = mVpixMax / static_cast<double>( mFps );
198 const double fieldLifeTime = mParticleLifeTime * mFps * fieldTimeStep;
199 mParticleField->setTimeStep( fieldTimeStep );
200 mParticleField->setParticlesLifeTime( fieldLifeTime );
201}
A block of integers/doubles from a mesh dataset.
@ DataOnFaces
Data is defined on faces.
@ DataOnVertices
Data is defined on vertices.
An index that identifies the dataset group (e.g.
int group() const
Returns a group index.
virtual int datasetGroupCount() const =0
Returns number of datasets groups loaded.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
QgsRectangle extent() const override
Returns the extent of the layer.
QgsMeshRendererSettings rendererSettings() const
Returns renderer settings.
QgsMeshDatasetIndex activeVectorDatasetAtTime(const QgsDateTimeRange &timeRange, int group=-1) const
Returns dataset index from active vector group depending on the time range If the temporal properties...
void reload() override
Synchronises with changes in the datasource.
QgsMesh * nativeMesh()
Returns native mesh (nullptr before rendering or calling to updateMesh).
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
QgsTriangularMesh * triangularMesh(double minimumTriangleSize=0) const
Returns triangular mesh (nullptr before rendering or calling to updateMesh).
QgsMeshLayerRendererCache * rendererCache()
Returns native mesh (nullptr before rendering).
QgsVectorFieldSettings vectorSettings(int groupIndex) const
Returns renderer settings.
Contains information about the context of a rendering operation.
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
Represents a renderer settings for vector datasets.
QgsVectorFieldTraceAnimationGenerator & operator=(const QgsVectorFieldTraceAnimationGenerator &other)
void setMinimumTailLength(int l)
Sets the minimum tail length.
QgsVectorFieldTraceAnimationGenerator(std::unique_ptr< QgsVectorFieldValueSource > source, const QgsRenderContext &rendererContext, const QgsVectorFieldSettings &vectorSettings, bool minimizeFieldSize=true)
Constructs a generator sampling the vector field from source, which is taken ownership of.
void seedRandomParticles(int count)
Seeds particles in the vector field.
void setParticlesSize(double width)
Sets particle size in px.
void setMaximumSpeedPixel(int pixels)
Sets the max number of pixels that can be go through by the particles in 1 second.
void setParticlesLifeTime(double particleLifeTime)
Sets maximum life time of particles in seconds.
void setTailFactor(double fct)
Sets the tail factor, used to adjust the length of the tail. 0 : minimum length, >1 increase the tail...
void setTailPersitence(double p)
Sets the visual persistence of the tail.
static QgsVectorFieldTraceAnimationGenerator * fromMeshLayer(QgsMeshLayer *layer, const QgsRenderContext &rendererContext)
Returns a generator for the active vector dataset of layer, or nullptr if the layer has no vector dat...
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...
void setFramesPerSecond(int frames)
Sets the number of frames per seconds that will be rendered.
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