QGIS API Documentation  3.6.0-Noosa (5873452)
qgs3dutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgs3dutils.cpp
3  --------------------------------------
4  Date : July 2017
5  Copyright : (C) 2017 by Martin Dobias
6  Email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgs3dutils.h"
17 
18 #include "qgslinestring.h"
19 #include "qgspolygon.h"
20 #include "qgsfeaturerequest.h"
21 #include "qgsfeatureiterator.h"
22 #include "qgsfeature.h"
23 #include "qgsabstractgeometry.h"
24 #include "qgsvectorlayer.h"
26 
27 #include "qgs3dmapscene.h"
28 #include "qgsabstract3dengine.h"
29 #include "qgsterraingenerator.h"
30 
31 #include "qgsline3dsymbol.h"
32 #include "qgspoint3dsymbol.h"
33 #include "qgspolygon3dsymbol.h"
34 
35 #include <Qt3DExtras/QPhongMaterial>
36 
37 
39 {
40  QImage resImage;
41  QEventLoop evLoop;
42 
43  auto requestImageFcn = [&engine, scene]
44  {
45  if ( scene->sceneState() == Qgs3DMapScene::Ready )
46  {
47  engine.requestCaptureImage();
48  }
49  };
50 
51  auto saveImageFcn = [&evLoop, &resImage]( const QImage & img )
52  {
53  resImage = img;
54  evLoop.quit();
55  };
56 
57  QMetaObject::Connection conn1 = QObject::connect( &engine, &QgsAbstract3DEngine::imageCaptured, saveImageFcn );
58  QMetaObject::Connection conn2;
59 
60  if ( scene->sceneState() == Qgs3DMapScene::Ready )
61  {
62  requestImageFcn();
63  }
64  else
65  {
66  // first wait until scene is loaded
67  conn2 = QObject::connect( scene, &Qgs3DMapScene::sceneStateChanged, requestImageFcn );
68  }
69 
70  evLoop.exec();
71 
72  QObject::disconnect( conn1 );
73  if ( conn2 )
74  QObject::disconnect( conn2 );
75 
76  return resImage;
77 }
78 
79 
80 int Qgs3DUtils::maxZoomLevel( double tile0width, double tileResolution, double maxError )
81 {
82  if ( maxError <= 0 || tileResolution <= 0 || tile0width <= 0 )
83  return 0; // invalid input
84 
85  // derived from:
86  // tile width [map units] = tile0width / 2^zoomlevel
87  // tile error [map units] = tile width / tile resolution
88  // + re-arranging to get zoom level if we know tile error we want to get
89  double zoomLevel = -log( tileResolution * maxError / tile0width ) / log( 2 );
90  return round( zoomLevel ); // we could use ceil() here if we wanted to always get to the desired error
91 }
92 
94 {
95  switch ( altClamp )
96  {
97  case Qgs3DTypes::AltClampAbsolute: return QStringLiteral( "absolute" );
98  case Qgs3DTypes::AltClampRelative: return QStringLiteral( "relative" );
99  case Qgs3DTypes::AltClampTerrain: return QStringLiteral( "terrain" );
100  default: Q_ASSERT( false ); return QString();
101  }
102 }
103 
104 
106 {
107  if ( str == QLatin1String( "absolute" ) )
109  else if ( str == QLatin1String( "terrain" ) )
111  else // "relative" (default)
113 }
114 
115 
117 {
118  switch ( altBind )
119  {
120  case Qgs3DTypes::AltBindVertex: return QStringLiteral( "vertex" );
121  case Qgs3DTypes::AltBindCentroid: return QStringLiteral( "centroid" );
122  default: Q_ASSERT( false ); return QString();
123  }
124 }
125 
126 
128 {
129  if ( str == QLatin1String( "vertex" ) )
131  else // "centroid" (default)
133 }
134 
136 {
137  switch ( mode )
138  {
139  case Qgs3DTypes::NoCulling: return QStringLiteral( "no-culling" );
140  case Qgs3DTypes::Front: return QStringLiteral( "front" );
141  case Qgs3DTypes::Back: return QStringLiteral( "back" );
142  case Qgs3DTypes::FrontAndBack: return QStringLiteral( "front-and-back" );
143  }
144  return QString();
145 }
146 
148 {
149  if ( str == QStringLiteral( "front" ) )
150  return Qgs3DTypes::Front;
151  else if ( str == QStringLiteral( "back" ) )
152  return Qgs3DTypes::Back;
153  else if ( str == QStringLiteral( "front-and-back" ) )
155  else
156  return Qgs3DTypes::NoCulling;
157 }
158 
159 float Qgs3DUtils::clampAltitude( const QgsPoint &p, Qgs3DTypes::AltitudeClamping altClamp, Qgs3DTypes::AltitudeBinding altBind, float height, const QgsPoint &centroid, const Qgs3DMapSettings &map )
160 {
161  float terrainZ = 0;
162  if ( altClamp == Qgs3DTypes::AltClampRelative || altClamp == Qgs3DTypes::AltClampTerrain )
163  {
164  QgsPointXY pt = altBind == Qgs3DTypes::AltBindVertex ? p : centroid;
165  terrainZ = map.terrainGenerator()->heightAt( pt.x(), pt.y(), map );
166  }
167 
168  float geomZ = altClamp == Qgs3DTypes::AltClampAbsolute || altClamp == Qgs3DTypes::AltClampRelative ? p.z() : 0;
169 
170  float z = ( terrainZ + geomZ ) * map.terrainVerticalScale() + height;
171  return z;
172 }
173 
174 void Qgs3DUtils::clampAltitudes( QgsLineString *lineString, Qgs3DTypes::AltitudeClamping altClamp, Qgs3DTypes::AltitudeBinding altBind, const QgsPoint &centroid, float height, const Qgs3DMapSettings &map )
175 {
176  for ( int i = 0; i < lineString->nCoordinates(); ++i )
177  {
178  float terrainZ = 0;
179  if ( altClamp == Qgs3DTypes::AltClampRelative || altClamp == Qgs3DTypes::AltClampTerrain )
180  {
181  QgsPointXY pt;
182  if ( altBind == Qgs3DTypes::AltBindVertex )
183  {
184  pt.setX( lineString->xAt( i ) );
185  pt.setY( lineString->yAt( i ) );
186  }
187  else
188  {
189  pt.set( centroid.x(), centroid.y() );
190  }
191  terrainZ = map.terrainGenerator()->heightAt( pt.x(), pt.y(), map );
192  }
193 
194  float geomZ = 0;
195  if ( altClamp == Qgs3DTypes::AltClampAbsolute || altClamp == Qgs3DTypes::AltClampRelative )
196  geomZ = lineString->zAt( i );
197 
198  float z = ( terrainZ + geomZ ) * map.terrainVerticalScale() + height;
199  lineString->setZAt( i, z );
200  }
201 }
202 
203 
205 {
206  if ( !polygon->is3D() )
207  polygon->addZValue( 0 );
208 
209  QgsPoint centroid;
210  if ( altBind == Qgs3DTypes::AltBindCentroid )
211  centroid = polygon->centroid();
212 
213  QgsCurve *curve = const_cast<QgsCurve *>( polygon->exteriorRing() );
214  QgsLineString *lineString = qgsgeometry_cast<QgsLineString *>( curve );
215  if ( !lineString )
216  return false;
217 
218  clampAltitudes( lineString, altClamp, altBind, centroid, height, map );
219 
220  for ( int i = 0; i < polygon->numInteriorRings(); ++i )
221  {
222  QgsCurve *curve = const_cast<QgsCurve *>( polygon->interiorRing( i ) );
223  QgsLineString *lineString = qgsgeometry_cast<QgsLineString *>( curve );
224  if ( !lineString )
225  return false;
226 
227  clampAltitudes( lineString, altClamp, altBind, centroid, height, map );
228  }
229  return true;
230 }
231 
232 
233 QString Qgs3DUtils::matrix4x4toString( const QMatrix4x4 &m )
234 {
235  const float *d = m.constData();
236  QStringList elems;
237  elems.reserve( 16 );
238  for ( int i = 0; i < 16; ++i )
239  elems << QString::number( d[i] );
240  return elems.join( ' ' );
241 }
242 
243 QMatrix4x4 Qgs3DUtils::stringToMatrix4x4( const QString &str )
244 {
245  QMatrix4x4 m;
246  float *d = m.data();
247  QStringList elems = str.split( ' ' );
248  for ( int i = 0; i < 16; ++i )
249  d[i] = elems[i].toFloat();
250  return m;
251 }
252 
253 void Qgs3DUtils::extractPointPositions( QgsFeature &f, const Qgs3DMapSettings &map, Qgs3DTypes::AltitudeClamping altClamp, QVector<QVector3D> &positions )
254 {
255  const QgsAbstractGeometry *g = f.geometry().constGet();
256  for ( auto it = g->vertices_begin(); it != g->vertices_end(); ++it )
257  {
258  QgsPoint pt = *it;
259  float geomZ = 0;
260  if ( pt.is3D() )
261  {
262  geomZ = pt.z();
263  }
264  float terrainZ = map.terrainGenerator()->heightAt( pt.x(), pt.y(), map ) * map.terrainVerticalScale();
265  float h;
266  switch ( altClamp )
267  {
269  default:
270  h = geomZ;
271  break;
273  h = terrainZ;
274  break;
276  h = terrainZ + geomZ;
277  break;
278  }
279  positions.append( QVector3D( pt.x() - map.origin().x(), h, -( pt.y() - map.origin().y() ) ) );
280  //qDebug() << positions.last();
281  }
282 }
283 
289 static inline uint outcode( QVector4D v )
290 {
291  // For a discussion of outcodes see pg 388 Dunn & Parberry.
292  // For why you can't just test if the point is in a bounding box
293  // consider the case where a view frustum with view-size 1.5 x 1.5
294  // is tested against a 2x2 box which encloses the near-plane, while
295  // all the points in the box are outside the frustum.
296  // TODO: optimise this with assembler - according to D&P this can
297  // be done in one line of assembler on some platforms
298  uint code = 0;
299  if ( v.x() < -v.w() ) code |= 0x01;
300  if ( v.x() > v.w() ) code |= 0x02;
301  if ( v.y() < -v.w() ) code |= 0x04;
302  if ( v.y() > v.w() ) code |= 0x08;
303  if ( v.z() < -v.w() ) code |= 0x10;
304  if ( v.z() > v.w() ) code |= 0x20;
305  return code;
306 }
307 
308 
319 bool Qgs3DUtils::isCullable( const QgsAABB &bbox, const QMatrix4x4 &viewProjectionMatrix )
320 {
321  uint out = 0xff;
322 
323  for ( int i = 0; i < 8; ++i )
324  {
325  QVector4D p( ( ( i >> 0 ) & 1 ) ? bbox.xMin : bbox.xMax,
326  ( ( i >> 1 ) & 1 ) ? bbox.yMin : bbox.yMax,
327  ( ( i >> 2 ) & 1 ) ? bbox.zMin : bbox.zMax, 1 );
328  QVector4D pc = viewProjectionMatrix * p;
329 
330  // if the logical AND of all the outcodes is non-zero then the BB is
331  // definitely outside the view frustum.
332  out = out & outcode( pc );
333  }
334  return out;
335 }
336 
338 {
339  return QgsVector3D( mapCoords.x() - origin.x(),
340  mapCoords.z() - origin.z(),
341  -( mapCoords.y() - origin.y() ) );
342 
343 }
344 
346 {
347  return QgsVector3D( worldCoords.x() + origin.x(),
348  -worldCoords.z() + origin.y(),
349  worldCoords.y() + origin.z() );
350 }
351 
353 {
354  QgsVector3D mapPoint1 = worldToMapCoordinates( worldPoint1, origin1 );
355  QgsVector3D mapPoint2 = mapPoint1;
356  if ( crs1 != crs2 )
357  {
358  // reproject if necessary
359  QgsCoordinateTransform ct( crs1, crs2, context );
360  try
361  {
362  QgsPointXY pt = ct.transform( QgsPointXY( mapPoint1.x(), mapPoint1.y() ) );
363  mapPoint2.set( pt.x(), pt.y(), mapPoint1.z() );
364  }
365  catch ( const QgsCsException & )
366  {
367  // bad luck, can't reproject for some reason
368  }
369  }
370  return mapToWorldCoordinates( mapPoint2, origin2 );
371 }
372 
373 std::unique_ptr<QgsAbstract3DSymbol> Qgs3DUtils::symbolForGeometryType( QgsWkbTypes::GeometryType geomType )
374 {
375  switch ( geomType )
376  {
378  return std::unique_ptr<QgsAbstract3DSymbol>( new QgsPoint3DSymbol );
380  return std::unique_ptr<QgsAbstract3DSymbol>( new QgsLine3DSymbol );
382  return std::unique_ptr<QgsAbstract3DSymbol>( new QgsPolygon3DSymbol );
383  default:
384  return nullptr;
385  }
386 }
387 
389 {
390  QgsExpressionContext exprContext;
394  return exprContext;
395 }
396 
397 Qt3DExtras::QPhongMaterial *Qgs3DUtils::phongMaterial( const QgsPhongMaterialSettings &settings )
398 {
399  Qt3DExtras::QPhongMaterial *phong = new Qt3DExtras::QPhongMaterial;
400  phong->setAmbient( settings.ambient() );
401  phong->setDiffuse( settings.diffuse() );
402  phong->setSpecular( settings.specular() );
403  phong->setShininess( settings.shininess() );
404  return phong;
405 }
AltitudeClamping
how to handle altitude of vector features
Definition: qgs3dtypes.h:34
3 Class for storage of 3D vectors similar to QVector3D, with the difference that it uses double preci...
Definition: qgsvector3d.h:31
3 Axis-aligned bounding box - in world coords.
Definition: qgsaabb.h:30
void set(double x, double y)
Sets the x and y value of the point.
Definition: qgspointxy.h:119
float shininess() const
Returns shininess of the surface.
double y
Definition: qgspoint.h:42
static std::unique_ptr< QgsAbstract3DSymbol > symbolForGeometryType(QgsWkbTypes::GeometryType geomType)
Returns a new 3D symbol based on given geometry type (or null pointer if geometry type is not support...
Definition: qgs3dutils.cpp:373
static QString altClampingToString(Qgs3DTypes::AltitudeClamping altClamp)
Converts a value from AltitudeClamping enum to a string.
Definition: qgs3dutils.cpp:93
static Qgs3DTypes::CullingMode cullingModeFromString(const QString &str)
Converts a string to a value from CullingMode enum.
Definition: qgs3dutils.cpp:147
virtual float heightAt(double x, double y, const Qgs3DMapSettings &map) const
Returns height at (x,y) in terrain&#39;s CRS.
double zAt(int index) const
Returns the z-coordinate of the specified node in the line string.
QgsPointXY transform(const QgsPointXY &point, TransformDirection direction=ForwardTransform) const SIP_THROW(QgsCsException)
Transform the point from the source CRS to the destination CRS.
QColor specular() const
Returns specular color component.
double y
Definition: qgspointxy.h:48
A class to represent a 2D point.
Definition: qgspointxy.h:43
const QgsCurve * interiorRing(int i) const
Retrieves an interior ring from the curve polygon.
static Qt3DExtras::QPhongMaterial * phongMaterial(const QgsPhongMaterialSettings &settings)
Returns phong material object based on the material settings.
Definition: qgs3dutils.cpp:397
float zMax
Definition: qgsaabb.h:80
3 3D symbol that draws polygon geometries as planar polygons, optionally extruded (with added walls)...
CullingMode
Triangle culling mode.
Definition: qgs3dtypes.h:49
static Qgs3DTypes::AltitudeClamping altClampingFromString(const QString &str)
Converts a string to a value from AltitudeClamping enum.
Definition: qgs3dutils.cpp:105
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
static bool isCullable(const QgsAABB &bbox, const QMatrix4x4 &viewProjectionMatrix)
Returns true if bbox is completely outside the current viewing volume.
Definition: qgs3dutils.cpp:319
Will not render anything.
Definition: qgs3dtypes.h:54
3 Basic shading material used for rendering based on the Phong shading model with three color compone...
double y() const
Returns Y coordinate.
Definition: qgsvector3d.h:51
3 Definition of the world
Z_final = z_geometry.
Definition: qgs3dtypes.h:36
void set(double x, double y, double z)
Sets vector coordinates.
Definition: qgsvector3d.h:56
QgsVector3D origin() const
Returns coordinates in map CRS at which 3D scene has origin (0,0,0)
virtual QgsPoint centroid() const
Returns the centroid of the geometry.
Clamp every vertex of feature.
Definition: qgs3dtypes.h:44
float zMin
Definition: qgsaabb.h:77
int numInteriorRings() const
Returns the number of interior rings contained with the curve polygon.
Will render only front faces of triangles (recommended when input data are consistent) ...
Definition: qgs3dtypes.h:53
double z() const
Returns Z coordinate.
Definition: qgsvector3d.h:53
static QgsVector3D worldToMapCoordinates(const QgsVector3D &worldCoords, const QgsVector3D &origin)
Converts 3D world coordinates to map coordinates (applies offset and turns (x,y,z) into (x...
Definition: qgs3dutils.cpp:345
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
float yMax
Definition: qgsaabb.h:79
static void extractPointPositions(QgsFeature &f, const Qgs3DMapSettings &map, Qgs3DTypes::AltitudeClamping altClamp, QVector< QVector3D > &positions)
Calculates (x,y,z) positions of (multi)point from the given feature.
Definition: qgs3dutils.cpp:253
static QString cullingModeToString(Qgs3DTypes::CullingMode mode)
Converts a value from CullingMode enum to a string.
Definition: qgs3dutils.cpp:135
Will render only back faces of triangles.
Definition: qgs3dtypes.h:52
Will render both front and back faces of triangles.
Definition: qgs3dtypes.h:51
3 3D symbol that draws point geometries as 3D objects using one of the predefined shapes...
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
SceneState sceneState() const
Returns the current state of the scene.
Definition: qgs3dmapscene.h:79
virtual void requestCaptureImage()=0
Starts a request for an image rendered by the engine.
double yAt(int index) const override
Returns the y-coordinate of the specified node in the line string.
void setY(double y)
Sets the y value of the point.
Definition: qgspointxy.h:113
vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry...
T qgsgeometry_cast(const QgsAbstractGeometry *geom)
static QgsVector3D mapToWorldCoordinates(const QgsVector3D &mapCoords, const QgsVector3D &origin)
Converts map coordinates to 3D world coordinates (applies offset and turns (x,y,z) into (x...
Definition: qgs3dutils.cpp:337
3 Base class for 3D engine implementation.
static float clampAltitude(const QgsPoint &p, Qgs3DTypes::AltitudeClamping altClamp, Qgs3DTypes::AltitudeBinding altBind, float height, const QgsPoint &centroid, const Qgs3DMapSettings &map)
Clamps altitude of a vertex according to the settings, returns Z value.
Definition: qgs3dutils.cpp:159
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
3 3D symbol that draws linestring geometries as planar polygons (created from lines using a buffer wi...
The scene is fully loaded/updated.
Definition: qgs3dmapscene.h:74
Abstract base class for all geometries.
Contains information about the context in which a coordinate transform is executed.
static int maxZoomLevel(double tile0width, double tileResolution, double maxError)
Calculates the highest needed zoom level for tiles in quad-tree given width of the base tile (zoom le...
Definition: qgs3dutils.cpp:80
void setZAt(int index, double z)
Sets the z-coordinate of the specified node in the line string.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
AltitudeBinding
how to handle clamping of vertices of individual features
Definition: qgs3dtypes.h:42
float xMin
Definition: qgsaabb.h:75
void setX(double x)
Sets the x value of the point.
Definition: qgspointxy.h:104
double x
Definition: qgspointxy.h:47
double terrainVerticalScale() const
Returns vertical scale (exaggeration) of terrain.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static QImage captureSceneImage(QgsAbstract3DEngine &engine, Qgs3DMapScene *scene)
Captures image of the current 3D scene of a 3D engine.
Definition: qgs3dutils.cpp:38
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:138
float xMax
Definition: qgsaabb.h:78
3 Entity that encapsulates our 3D scene - contains all other entities (such as terrain) as children...
Definition: qgs3dmapscene.h:53
void imageCaptured(const QImage &image)
Emitted after a call to requestCaptureImage() to return the captured image.
Z_final = z_terrain.
Definition: qgs3dtypes.h:38
static QMatrix4x4 stringToMatrix4x4(const QString &str)
Convert a string to a 4x4 transform matrix.
Definition: qgs3dutils.cpp:243
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:43
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:430
float yMin
Definition: qgsaabb.h:76
This class represents a coordinate reference system (CRS).
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
void sceneStateChanged()
Emitted when the scene&#39;s state has changed.
static Qgs3DTypes::AltitudeBinding altBindingFromString(const QString &str)
Converts a string to a value from AltitudeBinding enum.
Definition: qgs3dutils.cpp:127
Class for doing transforms between two map coordinate systems.
QColor ambient() const
Returns ambient color component.
double xAt(int index) const override
Returns the x-coordinate of the specified node in the line string.
static QgsExpressionContext globalProjectLayerExpressionContext(QgsVectorLayer *layer)
Returns expression context for use in preparation of 3D data of a layer.
Definition: qgs3dutils.cpp:388
static void clampAltitudes(QgsLineString *lineString, Qgs3DTypes::AltitudeClamping altClamp, Qgs3DTypes::AltitudeBinding altBind, const QgsPoint &centroid, float height, const Qgs3DMapSettings &map)
Clamps altitude of vertices of a linestring according to the settings.
Definition: qgs3dutils.cpp:174
QColor diffuse() const
Returns diffuse color component.
double z
Definition: qgspoint.h:43
QgsGeometry geometry
Definition: qgsfeature.h:67
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
static QgsVector3D transformWorldCoordinates(const QgsVector3D &worldPoint1, const QgsVector3D &origin1, const QgsCoordinateReferenceSystem &crs1, const QgsVector3D &origin2, const QgsCoordinateReferenceSystem &crs2, const QgsCoordinateTransformContext &context)
Transforms a world point from (origin1, crs1) to (origin2, crs2)
Definition: qgs3dutils.cpp:352
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
Polygon geometry type.
Definition: qgspolygon.h:31
const QgsCurve * exteriorRing() const
Returns the curve polygon&#39;s exterior ring.
int nCoordinates() const override
Returns the number of nodes contained in the geometry.
Represents a vector layer which manages a vector based data sets.
Z_final = z_terrain + z_geometry.
Definition: qgs3dtypes.h:37
static QString matrix4x4toString(const QMatrix4x4 &m)
Converts a 4x4 transform matrix to a string.
Definition: qgs3dutils.cpp:233
static QString altBindingToString(Qgs3DTypes::AltitudeBinding altBind)
Converts a value from AltitudeBinding enum to a string.
Definition: qgs3dutils.cpp:116
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
Clamp just centroid of feature.
Definition: qgs3dtypes.h:45
double x() const
Returns X coordinate.
Definition: qgsvector3d.h:49
QgsTerrainGenerator * terrainGenerator() const
Returns terrain generator. It takes care of producing terrain tiles from the input data...
double x
Definition: qgspoint.h:41