QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgslinevertexdata_p.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslinevertexdata_p.cpp
3  --------------------------------------
4  Date : Apr 2019
5  Copyright : (C) 2019 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 "qgslinevertexdata_p.h"
17 
18 #include <Qt3DRender/QAttribute>
19 #include <Qt3DRender/QBuffer>
20 #include <Qt3DRender/QGeometry>
21 
22 #include "qgslogger.h"
23 #include "qgs3dutils.h"
24 #include "qgslinestring.h"
25 
27 
28 
29 QgsLineVertexData::QgsLineVertexData()
30 {
31  // the first index is invalid, we use it for primitive restart
32  vertices << QVector3D();
33 }
34 
35 void QgsLineVertexData::init( Qgs3DTypes::AltitudeClamping clamping, Qgs3DTypes::AltitudeBinding binding, float height, const Qgs3DMapSettings *map )
36 {
37  altClamping = clamping;
38  altBinding = binding;
39  baseHeight = height;
40  mapSettings = map;
41 }
42 
43 QByteArray QgsLineVertexData::createVertexBuffer()
44 {
45  QByteArray vertexBufferData;
46  vertexBufferData.resize( vertices.size() * 3 * sizeof( float ) );
47  float *rawVertexArray = reinterpret_cast<float *>( vertexBufferData.data() );
48  int idx = 0;
49  for ( const auto &v : qgis::as_const( vertices ) )
50  {
51  rawVertexArray[idx++] = v.x();
52  rawVertexArray[idx++] = v.y();
53  rawVertexArray[idx++] = v.z();
54  }
55  return vertexBufferData;
56 }
57 
58 QByteArray QgsLineVertexData::createIndexBuffer()
59 {
60  QByteArray indexBufferData;
61  indexBufferData.resize( indexes.size() * sizeof( int ) );
62  unsigned int *rawIndexArray = reinterpret_cast<unsigned int *>( indexBufferData.data() );
63  int idx = 0;
64  for ( unsigned int indexVal : qgis::as_const( indexes ) )
65  {
66  rawIndexArray[idx++] = indexVal;
67  }
68  return indexBufferData;
69 }
70 
71 Qt3DRender::QGeometry *QgsLineVertexData::createGeometry( Qt3DCore::QNode *parent )
72 {
73 #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
74  Qt3DRender::QBuffer *vertexBuffer = new Qt3DRender::QBuffer( Qt3DRender::QBuffer::VertexBuffer, parent );
75 #else
76  Qt3DRender::QBuffer *vertexBuffer = new Qt3DRender::QBuffer( parent );
77 #endif
78  vertexBuffer->setData( createVertexBuffer() );
79 
80 #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
81  Qt3DRender::QBuffer *indexBuffer = new Qt3DRender::QBuffer( Qt3DRender::QBuffer::IndexBuffer, parent );
82 #else
83  Qt3DRender::QBuffer *indexBuffer = new Qt3DRender::QBuffer( parent );
84 #endif
85  indexBuffer->setData( createIndexBuffer() );
86 
87  QgsDebugMsg( QString( "vertex buffer %1 MB index buffer %2 MB " ).arg( vertexBuffer->data().count() / 1024. / 1024. ).arg( indexBuffer->data().count() / 1024. / 1024. ) );
88 
89  Qt3DRender::QAttribute *positionAttribute = new Qt3DRender::QAttribute( parent );
90  positionAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
91  positionAttribute->setBuffer( vertexBuffer );
92  positionAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
93  positionAttribute->setVertexSize( 3 );
94  positionAttribute->setName( Qt3DRender::QAttribute::defaultPositionAttributeName() );
95 
96  Qt3DRender::QAttribute *indexAttribute = new Qt3DRender::QAttribute( parent );
97  indexAttribute->setAttributeType( Qt3DRender::QAttribute::IndexAttribute );
98  indexAttribute->setBuffer( indexBuffer );
99  indexAttribute->setVertexBaseType( Qt3DRender::QAttribute::UnsignedInt );
100 
101  Qt3DRender::QGeometry *geom = new Qt3DRender::QGeometry;
102  geom->addAttribute( positionAttribute );
103  geom->addAttribute( indexAttribute );
104  return geom;
105 }
106 
107 void QgsLineVertexData::addLineString( const QgsLineString &lineString, float extraHeightOffset )
108 {
109  if ( withAdjacency )
110  indexes << vertices.count(); // add the following vertex (for adjacency)
111 
112  QgsPoint centroid;
113  if ( altBinding == Qgs3DTypes::AltBindCentroid )
114  centroid = lineString.centroid();
115 
116  for ( int i = 0; i < lineString.vertexCount(); ++i )
117  {
118  QgsPoint p = lineString.pointN( i );
119  float z = Qgs3DUtils::clampAltitude( p, altClamping, altBinding, baseHeight + extraHeightOffset, centroid, *mapSettings );
120 
121  vertices << QVector3D( p.x() - mapSettings->origin().x(), z, -( p.y() - mapSettings->origin().y() ) );
122  indexes << vertices.count() - 1;
123  }
124 
125  if ( withAdjacency )
126  indexes << vertices.count() - 1; // add the last vertex (for adjacency)
127 
128  indexes << 0; // add primitive restart
129 }
130 
131 
132 void QgsLineVertexData::addVerticalLines( const QgsLineString &lineString, float verticalLength, float extraHeightOffset )
133 {
134  QgsPoint centroid;
135  if ( altBinding == Qgs3DTypes::AltBindCentroid )
136  centroid = lineString.centroid();
137 
138  for ( int i = 0; i < lineString.vertexCount(); ++i )
139  {
140  QgsPoint p = lineString.pointN( i );
141  float z = Qgs3DUtils::clampAltitude( p, altClamping, altBinding, baseHeight + extraHeightOffset, centroid, *mapSettings );
142  float z2 = z + verticalLength;
143 
144  if ( withAdjacency )
145  indexes << vertices.count(); // add the following vertex (for adjacency)
146 
147  vertices << QVector3D( p.x() - mapSettings->origin().x(), z, -( p.y() - mapSettings->origin().y() ) );
148  indexes << vertices.count() - 1;
149  vertices << QVector3D( p.x() - mapSettings->origin().x(), z2, -( p.y() - mapSettings->origin().y() ) );
150  indexes << vertices.count() - 1;
151 
152  if ( withAdjacency )
153  indexes << vertices.count() - 1; // add the last vertex (for adjacency)
154 
155  indexes << 0; // add primitive restart
156  }
157 }
158 
159 
Qgs3DUtils::clampAltitude
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:250
QgsLineString::pointN
QgsPoint pointN(int i) const
Returns the specified point from inside the line string.
Definition: qgslinestring.cpp:660
Qgs3DTypes::AltitudeBinding
AltitudeBinding
how to handle clamping of vertices of individual features
Definition: qgs3dtypes.h:55
qgslinestring.h
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
QgsLineString::centroid
QgsPoint centroid() const override
Returns the centroid of the geometry.
Definition: qgslinestring.cpp:1398
Qgs3DTypes::AltBindCentroid
@ AltBindCentroid
Clamp just centroid of feature.
Definition: qgs3dtypes.h:58
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsLineString
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:43
QgsPoint::y
double y
Definition: qgspoint.h:59
qgs3dutils.h
Qgs3DMapSettings
Definition: qgs3dmapsettings.h:51
Qgs3DTypes::AltitudeClamping
AltitudeClamping
how to handle altitude of vector features
Definition: qgs3dtypes.h:47
QgsCurve::vertexCount
int vertexCount(int part=0, int ring=0) const override
Returns the number of vertices of which this geometry is built.
Definition: qgscurve.cpp:164
qgslogger.h
qgslinevertexdata_p.h
QgsPoint::x
double x
Definition: qgspoint.h:58