QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsmeshvectorrenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmeshvectorrenderer.cpp
3  -------------------------
4  begin : May 2018
5  copyright : (C) 2018 by Peter Petrik
6  email : zilolv 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 #include "qgsmeshvectorrenderer.h"
19 #include "qgsrendercontext.h"
20 #include "qgscoordinatetransform.h"
21 #include "qgsmaptopixel.h"
22 #include "qgsunittypes.h"
23 #include "qgsmeshlayerutils.h"
24 #include "qgsmeshtracerenderer.h"
25 
26 #include <cstdlib>
27 #include <ctime>
28 #include <algorithm>
29 #include <QPen>
30 #include <QPainter>
31 #include <cmath>
32 
34 
35 inline double mag( double input )
36 {
37  if ( input < 0.0 )
38  {
39  return -1.0;
40  }
41  return 1.0;
42 }
43 
44 inline bool nodataValue( double x, double y )
45 {
46  return ( std::isnan( x ) || std::isnan( y ) );
47 }
48 
49 QgsMeshVectorArrowRenderer::QgsMeshVectorArrowRenderer(
50  const QgsTriangularMesh &m,
51  const QgsMeshDataBlock &datasetValues,
52  const QVector<double> &datasetValuesMag,
53  double datasetMagMaximumValue, double datasetMagMinimumValue,
55  const QgsMeshRendererVectorSettings &settings,
56  QgsRenderContext &context,
57  QSize size ) :
58  mTriangularMesh( m )
59  , mDatasetValues( datasetValues )
60  , mDatasetValuesMag( datasetValuesMag )
61  , mMinMag( datasetMagMinimumValue )
62  , mMaxMag( datasetMagMaximumValue )
63  , mContext( context )
64  , mCfg( settings )
65  , mDataType( dataType )
66  , mOutputSize( size )
67  , mBufferedExtent( context.mapExtent() )
68 {
69  // should be checked in caller
70  Q_ASSERT( !mDatasetValuesMag.empty() );
71  Q_ASSERT( !std::isnan( mMinMag ) );
72  Q_ASSERT( !std::isnan( mMaxMag ) );
73  Q_ASSERT( mDatasetValues.isValid() );
74  Q_ASSERT( QgsMeshDataBlock::Vector2DDouble == mDatasetValues.type() );
75 
76  // we need to expand out the extent so that it includes
77  // arrows which start or end up outside of the
78  // actual visible extent
79  double extension = context.convertToMapUnits( calcExtentBufferSize(), QgsUnitTypes::RenderPixels );
80  mBufferedExtent.setXMinimum( mBufferedExtent.xMinimum() - extension );
81  mBufferedExtent.setXMaximum( mBufferedExtent.xMaximum() + extension );
82  mBufferedExtent.setYMinimum( mBufferedExtent.yMinimum() - extension );
83  mBufferedExtent.setYMaximum( mBufferedExtent.yMaximum() + extension );
84 
85  mVectorColoring = settings.vectorStrokeColoring();
86 }
87 
88 QgsMeshVectorArrowRenderer::~QgsMeshVectorArrowRenderer() = default;
89 
90 void QgsMeshVectorArrowRenderer::draw()
91 {
92  // Set up the render configuration options
93  QPainter *painter = mContext.painter();
94  painter->save();
95  if ( mContext.flags() & QgsRenderContext::Antialiasing )
96  painter->setRenderHint( QPainter::Antialiasing, true );
97 
98  QPen pen = painter->pen();
99  pen.setCapStyle( Qt::FlatCap );
100  pen.setJoinStyle( Qt::MiterJoin );
101 
102  double penWidth = mContext.convertToPainterUnits( mCfg.lineWidth(),
103  QgsUnitTypes::RenderUnit::RenderMillimeters );
104  pen.setWidthF( penWidth );
105  painter->setPen( pen );
106 
107  if ( mCfg.isOnUserDefinedGrid() )
108  {
109  drawVectorDataOnGrid( );
110  }
111  else if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnVertices )
112  {
113  drawVectorDataOnVertices( );
114  }
115  else if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnFaces )
116  {
117  drawVectorDataOnFaces( );
118  }
119  else if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnEdges )
120  {
121  drawVectorDataOnEdges( );
122  }
123 
124  painter->restore();
125 }
126 
127 bool QgsMeshVectorArrowRenderer::calcVectorLineEnd(
128  QgsPointXY &lineEnd,
129  double &vectorLength,
130  double &cosAlpha,
131  double &sinAlpha, //out
132  const QgsPointXY &lineStart,
133  double xVal,
134  double yVal,
135  double magnitude //in
136 )
137 {
138  // return true on error
139 
140  if ( xVal == 0.0 && yVal == 0.0 )
141  return true;
142 
143  // do not render if magnitude is outside of the filtered range (if filtering is enabled)
144  if ( mCfg.filterMin() >= 0 && magnitude < mCfg.filterMin() )
145  return true;
146  if ( mCfg.filterMax() >= 0 && magnitude > mCfg.filterMax() )
147  return true;
148 
149  // Determine the angle of the vector, counter-clockwise, from east
150  // (and associated trigs)
151  double vectorAngle = -1.0 * atan( ( -1.0 * yVal ) / xVal );
152  cosAlpha = cos( vectorAngle ) * mag( xVal );
153  sinAlpha = sin( vectorAngle ) * mag( xVal );
154 
155  // Now determine the X and Y distances of the end of the line from the start
156  double xDist = 0.0;
157  double yDist = 0.0;
158  switch ( mCfg.arrowSettings().shaftLengthMethod() )
159  {
160  case QgsMeshRendererVectorArrowSettings::ArrowScalingMethod::MinMax:
161  {
162  double minShaftLength = mContext.convertToPainterUnits( mCfg.arrowSettings().minShaftLength(),
163  QgsUnitTypes::RenderUnit::RenderMillimeters );
164  double maxShaftLength = mContext.convertToPainterUnits( mCfg.arrowSettings().maxShaftLength(),
165  QgsUnitTypes::RenderUnit::RenderMillimeters );
166  double minVal = mMinMag;
167  double maxVal = mMaxMag;
168  double k = ( magnitude - minVal ) / ( maxVal - minVal );
169  double L = minShaftLength + k * ( maxShaftLength - minShaftLength );
170  xDist = cosAlpha * L;
171  yDist = sinAlpha * L;
172  break;
173  }
174  case QgsMeshRendererVectorArrowSettings::ArrowScalingMethod::Scaled:
175  {
176  double scaleFactor = mCfg.arrowSettings().scaleFactor();
177  xDist = scaleFactor * xVal;
178  yDist = scaleFactor * yVal;
179  break;
180  }
181  case QgsMeshRendererVectorArrowSettings::ArrowScalingMethod::Fixed:
182  {
183  // We must be using a fixed length
184  double fixedShaftLength = mContext.convertToPainterUnits( mCfg.arrowSettings().fixedShaftLength(),
185  QgsUnitTypes::RenderUnit::RenderMillimeters );
186  xDist = cosAlpha * fixedShaftLength;
187  yDist = sinAlpha * fixedShaftLength;
188  break;
189  }
190  }
191 
192  // Flip the Y axis (pixel vs real-world axis)
193  yDist *= -1.0;
194 
195  if ( std::abs( xDist ) < 1 && std::abs( yDist ) < 1 )
196  return true;
197 
198  // Determine the line coords
199  lineEnd = QgsPointXY( lineStart.x() + xDist,
200  lineStart.y() + yDist );
201 
202  vectorLength = sqrt( xDist * xDist + yDist * yDist );
203 
204  // Check to see if both of the coords are outside the QImage area, if so, skip the whole vector
205  if ( ( lineStart.x() < 0 || lineStart.x() > mOutputSize.width() ||
206  lineStart.y() < 0 || lineStart.y() > mOutputSize.height() ) &&
207  ( lineEnd.x() < 0 || lineEnd.x() > mOutputSize.width() ||
208  lineEnd.y() < 0 || lineEnd.y() > mOutputSize.height() ) )
209  return true;
210 
211  return false; //success
212 }
213 
214 double QgsMeshVectorArrowRenderer::calcExtentBufferSize() const
215 {
216  double buffer = 0;
217  switch ( mCfg.arrowSettings().shaftLengthMethod() )
218  {
219  case QgsMeshRendererVectorArrowSettings::ArrowScalingMethod::MinMax:
220  {
221  buffer = mContext.convertToPainterUnits( mCfg.arrowSettings().maxShaftLength(),
222  QgsUnitTypes::RenderUnit::RenderMillimeters );
223  break;
224  }
225  case QgsMeshRendererVectorArrowSettings::ArrowScalingMethod::Scaled:
226  {
227  buffer = mCfg.arrowSettings().scaleFactor() * mMaxMag;
228  break;
229  }
230  case QgsMeshRendererVectorArrowSettings::ArrowScalingMethod::Fixed:
231  {
232  buffer = mContext.convertToPainterUnits( mCfg.arrowSettings().fixedShaftLength(),
233  QgsUnitTypes::RenderUnit::RenderMillimeters );
234  break;
235  }
236  }
237 
238  if ( mCfg.filterMax() >= 0 && buffer > mCfg.filterMax() )
239  buffer = mCfg.filterMax();
240 
241  if ( buffer < 0.0 )
242  buffer = 0.0;
243 
244  return buffer;
245 }
246 
247 
248 void QgsMeshVectorArrowRenderer::drawVectorDataOnVertices()
249 {
250  const QVector<QgsMeshVertex> &vertices = mTriangularMesh.vertices();
251  QSet<int> verticesToDraw;
252 
253  // currently expecting that triangulation does not add any new extra vertices on the way
254  Q_ASSERT( mDatasetValuesMag.count() == vertices.count() );
255 
256  // find all vertices from faces to render
257  {
258  const QList<int> trianglesInExtent = mTriangularMesh.faceIndexesForRectangle( mBufferedExtent );
259  const QVector<QgsMeshFace> &triangles = mTriangularMesh.triangles();
260  verticesToDraw.unite( QgsMeshUtils::nativeVerticesFromTriangles( trianglesInExtent, triangles ) );
261  }
262 
263  // find all vertices from edges to render
264  {
265  const QList<int> edgesInExtent = mTriangularMesh.edgeIndexesForRectangle( mBufferedExtent );
266  const QVector<QgsMeshEdge> &edges = mTriangularMesh.edges();
267  verticesToDraw.unite( QgsMeshUtils::nativeVerticesFromEdges( edgesInExtent, edges ) );
268  }
269 
270  // render
271  drawVectorDataOnPoints( verticesToDraw, vertices );
272 }
273 
274 void QgsMeshVectorArrowRenderer::drawVectorDataOnPoints( const QSet<int> indexesToRender, const QVector<QgsMeshVertex> &points )
275 {
276  for ( int i : indexesToRender )
277  {
278  if ( mContext.renderingStopped() )
279  break;
280 
281  QgsPointXY center = points.at( i );
282  if ( !mBufferedExtent.contains( center ) )
283  continue;
284 
285  const QgsMeshDatasetValue val = mDatasetValues.value( i );
286  double xVal = val.x();
287  double yVal = val.y();
288  if ( nodataValue( xVal, yVal ) )
289  continue;
290 
291  double V = mDatasetValuesMag[i]; // pre-calculated magnitude
292  QgsPointXY lineStart = mContext.mapToPixel().transform( center.x(), center.y() );
293 
294  drawVectorArrow( lineStart, xVal, yVal, V );
295  }
296 }
297 
298 void QgsMeshVectorArrowRenderer::drawVectorDataOnFaces( )
299 {
300  const QList<int> trianglesInExtent = mTriangularMesh.faceIndexesForRectangle( mBufferedExtent );
301  const QVector<QgsMeshVertex> &centroids = mTriangularMesh.faceCentroids();
302  const QSet<int> nativeFacesInExtent = QgsMeshUtils::nativeFacesFromTriangles( trianglesInExtent,
303  mTriangularMesh.trianglesToNativeFaces() );
304  drawVectorDataOnPoints( nativeFacesInExtent, centroids );
305 }
306 
307 void QgsMeshVectorArrowRenderer::drawVectorDataOnEdges()
308 {
309  const QList<int> egdesInExtent = mTriangularMesh.edgeIndexesForRectangle( mBufferedExtent );
310  const QVector<QgsMeshVertex> &centroids = mTriangularMesh.edgeCentroids();
311  const QSet<int> nativeEdgesInExtent = QgsMeshUtils::nativeEdgesFromEdges( egdesInExtent,
312  mTriangularMesh.edgesToNativeEdges() );
313  drawVectorDataOnPoints( nativeEdgesInExtent, centroids );
314 }
315 
316 void QgsMeshVectorArrowRenderer::drawVectorDataOnGrid( )
317 {
318  if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnEdges ||
319  mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnVolumes )
320  return;
321 
322  const QList<int> trianglesInExtent = mTriangularMesh.faceIndexesForRectangle( mBufferedExtent );
323  int cellx = mCfg.userGridCellWidth();
324  int celly = mCfg.userGridCellHeight();
325 
326  const QVector<QgsMeshFace> &triangles = mTriangularMesh.triangles();
327  const QVector<QgsMeshVertex> &vertices = mTriangularMesh.vertices();
328 
329  for ( const int i : trianglesInExtent )
330  {
331  if ( mContext.renderingStopped() )
332  break;
333 
334  const QgsMeshFace &face = triangles[i];
335 
336  const int v1 = face[0], v2 = face[1], v3 = face[2];
337  const QgsPoint p1 = vertices[v1], p2 = vertices[v2], p3 = vertices[v3];
338 
339  const int nativeFaceIndex = mTriangularMesh.trianglesToNativeFaces()[i];
340 
341  // Get the BBox of the element in pixels
342  QgsRectangle bbox = QgsMeshLayerUtils::triangleBoundingBox( p1, p2, p3 );
343  int left, right, top, bottom;
344  QgsMeshLayerUtils::boundingBoxToScreenRectangle( mContext.mapToPixel(), mOutputSize, bbox, left, right, top, bottom );
345 
346  // Align rect to the grid (e.g. interval <13, 36> with grid cell 10 will be trimmed to <20,30>
347  if ( left % cellx != 0 )
348  left += cellx - ( left % cellx );
349  if ( right % cellx != 0 )
350  right -= ( right % cellx );
351  if ( top % celly != 0 )
352  top += celly - ( top % celly );
353  if ( bottom % celly != 0 )
354  bottom -= ( bottom % celly );
355 
356  for ( int y = top; y <= bottom; y += celly )
357  {
358  for ( int x = left; x <= right; x += cellx )
359  {
361  const QgsPointXY p = mContext.mapToPixel().toMapCoordinates( x, y );
362 
363  if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnVertices )
364  {
365  const auto val1 = mDatasetValues.value( v1 );
366  const auto val2 = mDatasetValues.value( v2 );
367  const auto val3 = mDatasetValues.value( v3 );
368  val.setX(
369  QgsMeshLayerUtils::interpolateFromVerticesData(
370  p1, p2, p3,
371  val1.x(),
372  val2.x(),
373  val3.x(),
374  p )
375  );
376  val.setY(
377  QgsMeshLayerUtils::interpolateFromVerticesData(
378  p1, p2, p3,
379  val1.y(),
380  val2.y(),
381  val3.y(),
382  p )
383  );
384  }
385  else if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnFaces )
386  {
387  const auto val1 = mDatasetValues.value( nativeFaceIndex );
388  val.setX(
389  QgsMeshLayerUtils::interpolateFromFacesData(
390  p1, p2, p3,
391  val1.x(),
392  p
393  )
394  );
395  val.setY(
396  QgsMeshLayerUtils::interpolateFromFacesData(
397  p1, p2, p3,
398  val1.y(),
399  p
400  )
401  );
402  }
403  if ( nodataValue( val.x(), val.y() ) )
404  continue;
405 
406  QgsPointXY lineStart( x, y );
407  drawVectorArrow( lineStart, val.x(), val.y(), val.scalar() );
408  }
409  }
410  }
411 }
412 
413 void QgsMeshVectorArrowRenderer::drawVectorArrow( const QgsPointXY &lineStart, double xVal, double yVal, double magnitude )
414 {
415  QgsPointXY lineEnd;
416  double vectorLength;
417  double cosAlpha, sinAlpha;
418  if ( calcVectorLineEnd( lineEnd, vectorLength, cosAlpha, sinAlpha,
419  lineStart, xVal, yVal, magnitude ) )
420  return;
421 
422  // Make a set of vector head coordinates that we will place at the end of each vector,
423  // scale, translate and rotate.
424  QgsPointXY vectorHeadPoints[3];
425  QVector<QPointF> finalVectorHeadPoints( 3 );
426 
427  double vectorHeadWidthRatio = mCfg.arrowSettings().arrowHeadWidthRatio();
428  double vectorHeadLengthRatio = mCfg.arrowSettings().arrowHeadLengthRatio();
429 
430  // First head point: top of ->
431  vectorHeadPoints[0].setX( -1.0 * vectorHeadLengthRatio );
432  vectorHeadPoints[0].setY( vectorHeadWidthRatio * 0.5 );
433 
434  // Second head point: right of ->
435  vectorHeadPoints[1].setX( 0.0 );
436  vectorHeadPoints[1].setY( 0.0 );
437 
438  // Third head point: bottom of ->
439  vectorHeadPoints[2].setX( -1.0 * vectorHeadLengthRatio );
440  vectorHeadPoints[2].setY( -1.0 * vectorHeadWidthRatio * 0.5 );
441 
442  // Determine the arrow head coords
443  for ( int j = 0; j < 3; j++ )
444  {
445  finalVectorHeadPoints[j].setX( lineEnd.x()
446  + ( vectorHeadPoints[j].x() * cosAlpha * vectorLength )
447  - ( vectorHeadPoints[j].y() * sinAlpha * vectorLength )
448  );
449 
450  finalVectorHeadPoints[j].setY( lineEnd.y()
451  - ( vectorHeadPoints[j].x() * sinAlpha * vectorLength )
452  - ( vectorHeadPoints[j].y() * cosAlpha * vectorLength )
453  );
454  }
455 
456  // Now actually draw the vector
457  QPen pen( mContext.painter()->pen() );
458  pen.setColor( mVectorColoring.color( magnitude ) );
459  mContext.painter()->setPen( pen );
460  mContext.painter()->drawLine( lineStart.toQPointF(), lineEnd.toQPointF() );
461  mContext.painter()->drawPolygon( finalVectorHeadPoints );
462 }
463 
464 QgsMeshVectorRenderer::~QgsMeshVectorRenderer() = default;
465 
466 QgsMeshVectorRenderer *QgsMeshVectorRenderer::makeVectorRenderer(
467  const QgsTriangularMesh &m,
468  const QgsMeshDataBlock &datasetVectorValues,
469  const QgsMeshDataBlock &scalarActiveFaceFlagValues,
470  const QVector<double> &datasetValuesMag,
471  double datasetMagMaximumValue,
472  double datasetMagMinimumValue,
474  const QgsMeshRendererVectorSettings &settings,
475  QgsRenderContext &context,
476  const QgsRectangle &layerExtent,
477  QSize size )
478 {
479  QgsMeshVectorRenderer *renderer = nullptr;
480 
481  switch ( settings.symbology() )
482  {
484  renderer = new QgsMeshVectorArrowRenderer(
485  m,
486  datasetVectorValues,
487  datasetValuesMag,
488  datasetMagMaximumValue,
489  datasetMagMinimumValue,
490  dataType,
491  settings,
492  context, size );
493  break;
495  renderer = new QgsMeshVectorStreamlineRenderer(
496  m,
497  datasetVectorValues,
498  scalarActiveFaceFlagValues,
499  dataType == QgsMeshDatasetGroupMetadata::DataType::DataOnVertices,
500  settings,
501  context,
502  layerExtent,
503  datasetMagMaximumValue );
504  break;
506  renderer = new QgsMeshVectorTraceRenderer(
507  m,
508  datasetVectorValues,
509  scalarActiveFaceFlagValues,
510  dataType == QgsMeshDatasetGroupMetadata::DataType::DataOnVertices,
511  settings,
512  context,
513  layerExtent,
514  datasetMagMaximumValue );
515  break;
516  }
517 
518  return renderer;
519 }
520 
521 
qgsmeshlayerutils.h
QgsMeshRendererVectorSettings
Definition: qgsmeshrenderersettings.h:410
QgsMeshRendererVectorSettings::Traces
@ Traces
Displaying vector dataset with particle traces.
Definition: qgsmeshrenderersettings.h:425
QgsMeshRendererVectorSettings::symbology
Symbology symbology() const
Returns the displaying method used to render vector datasets.
Definition: qgsmeshrenderersettings.cpp:567
QgsPointXY::y
double y
Definition: qgspointxy.h:48
QgsMeshDatasetValue::setY
void setY(double y)
Sets Y value.
Definition: qgsmeshdataset.cpp:88
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
QgsMeshUtils::nativeVerticesFromEdges
CORE_EXPORT QSet< int > nativeVerticesFromEdges(const QList< int > &edgesIndexes, const QVector< QgsMeshEdge > &edges)
Returns unique native faces indexes from list of vertices of triangles.
Definition: qgstriangularmesh.cpp:595
qgsmaptopixel.h
QgsMeshUtils::nativeVerticesFromTriangles
CORE_EXPORT QSet< int > nativeVerticesFromTriangles(const QList< int > &triangleIndexes, const QVector< QgsMeshFace > &triangles)
Returns unique native vertex indexes from list of vertices of triangles.
Definition: qgstriangularmesh.cpp:581
QgsMeshDatasetValue
Definition: qgsmeshdataset.h:76
QgsRenderContext::convertToMapUnits
double convertToMapUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to map units.
Definition: qgsrendercontext.cpp:349
QgsRenderContext
Definition: qgsrendercontext.h:57
QgsPointXY::toQPointF
QPointF toQPointF() const
Converts a point to a QPointF.
Definition: qgspointxy.h:154
qgsunittypes.h
QgsRectangle
Definition: qgsrectangle.h:41
QgsMeshUtils::nativeEdgesFromEdges
CORE_EXPORT QSet< int > nativeEdgesFromEdges(const QList< int > &edgesIndexes, const QVector< int > &edgesToNativeEdges)
Returns unique native faces indexes from list of triangle indexes.
Definition: qgstriangularmesh.cpp:545
QgsMeshRendererVectorSettings::vectorStrokeColoring
QgsInterpolatedLineColor vectorStrokeColoring() const
Returns the stroke coloring used to render vector datasets.
Definition: qgsmeshrenderersettings.cpp:671
QgsMeshUtils::nativeFacesFromTriangles
CORE_EXPORT QSet< int > nativeFacesFromTriangles(const QList< int > &triangleIndexes, const QVector< int > &trianglesToNativeFaces)
Returns unique native faces indexes from list of triangle indexes.
Definition: qgstriangularmesh.cpp:540
QgsMeshDataBlock::Vector2DDouble
@ Vector2DDouble
Vector double pairs (x1, y1, x2, y2, ... )
Definition: qgsmeshdataset.h:142
QgsMeshDatasetValue::x
double x() const
Returns x value.
Definition: qgsmeshdataset.cpp:93
qgsrendercontext.h
QgsPointXY::setY
void setY(double y)
Sets the y value of the point.
Definition: qgspointxy.h:117
qgscoordinatetransform.h
QgsMeshRendererVectorSettings::Streamlines
@ Streamlines
Displaying vector dataset with streamlines.
Definition: qgsmeshrenderersettings.h:423
QgsMeshFace
QVector< int > QgsMeshFace
List of vertex indexes.
Definition: qgsmeshdataprovider.h:41
QgsUnitTypes::RenderPixels
@ RenderPixels
Pixels.
Definition: qgsunittypes.h:170
QgsPointXY
Definition: qgspointxy.h:43
QgsMeshRendererVectorSettings::Arrows
@ Arrows
Displaying vector dataset with arrows.
Definition: qgsmeshrenderersettings.h:421
qgsmeshtracerenderer.h
qgsmeshvectorrenderer.h
QgsMeshDatasetGroupMetadata::DataType
DataType
Location of where data is specified for datasets in the dataset group.
Definition: qgsmeshdataset.h:353
QgsPointXY::x
double x
Definition: qgspointxy.h:47
QgsMeshDatasetValue::y
double y() const
Returns y value.
Definition: qgsmeshdataset.cpp:98
QgsMeshDatasetValue::setX
void setX(double x)
Sets X value.
Definition: qgsmeshdataset.cpp:83
QgsRenderContext::Antialiasing
@ Antialiasing
Use antialiasing while drawing.
Definition: qgsrendercontext.h:78
QgsMeshDataBlock
Definition: qgsmeshdataset.h:134
QgsPointXY::setX
void setX(double x)
Sets the x value of the point.
Definition: qgspointxy.h:107
QgsTriangularMesh
Definition: qgstriangularmesh.h:49
QgsMeshDatasetValue::scalar
double scalar() const
Returns magnitude of vector for vector data or scalar value for scalar data.
Definition: qgsmeshdataset.cpp:62