QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
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 "qgs3dutils.h"
20#include "qgslinestring.h"
21#include "qgslogger.h"
22
23#include <Qt3DCore/QAttribute>
24#include <Qt3DCore/QBuffer>
25#include <Qt3DCore/QGeometry>
26
28
29
30QgsLineVertexData::QgsLineVertexData()
31{
32 // the first index is invalid, we use it for primitive restart
33 vertices << QVector3D();
34}
35
36void QgsLineVertexData::init( Qgis::AltitudeClamping clamping, Qgis::AltitudeBinding binding, float height, const Qgs3DRenderContext &context, const QgsVector3D &chunkOrigin )
37{
38 altClamping = clamping;
39 altBinding = binding;
40 baseHeight = height;
41 renderContext = context;
42 origin = chunkOrigin;
43}
44
45QByteArray QgsLineVertexData::createVertexBuffer()
46{
47 QByteArray vertexBufferData;
48 vertexBufferData.resize( vertices.size() * 3 * sizeof( float ) );
49 float *rawVertexArray = reinterpret_cast<float *>( vertexBufferData.data() );
50 int idx = 0;
51 for ( const auto &v : std::as_const( vertices ) )
52 {
53 rawVertexArray[idx++] = v.x();
54 rawVertexArray[idx++] = v.y();
55 rawVertexArray[idx++] = v.z();
56 }
57 return vertexBufferData;
58}
59
60QByteArray QgsLineVertexData::createIndexBuffer()
61{
62 QByteArray indexBufferData;
63 indexBufferData.resize( indexes.size() * sizeof( int ) );
64 unsigned int *rawIndexArray = reinterpret_cast<unsigned int *>( indexBufferData.data() );
65 int idx = 0;
66 for ( unsigned int indexVal : std::as_const( indexes ) )
67 {
68 rawIndexArray[idx++] = indexVal;
69 }
70 return indexBufferData;
71}
72
73Qt3DCore::QGeometry *QgsLineVertexData::createGeometry( Qt3DCore::QNode *parent )
74{
75 Qt3DCore::QBuffer *vertexBuffer = new Qt3DCore::QBuffer( parent );
76 vertexBuffer->setData( createVertexBuffer() );
77
78 Qt3DCore::QBuffer *indexBuffer = new Qt3DCore::QBuffer( parent );
79 indexBuffer->setData( createIndexBuffer() );
80
81 QgsDebugMsgLevel( QString( "vertex buffer %1 MB index buffer %2 MB " ).arg( vertexBuffer->data().count() / 1024. / 1024. ).arg( indexBuffer->data().count() / 1024. / 1024. ), 2 );
82
83 Qt3DCore::QAttribute *positionAttribute = new Qt3DCore::QAttribute( parent );
84 positionAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
85 positionAttribute->setBuffer( vertexBuffer );
86 positionAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
87 positionAttribute->setVertexSize( 3 );
88 positionAttribute->setByteStride( 3 * sizeof( float ) );
89 positionAttribute->setByteOffset( 0 );
90 positionAttribute->setName( Qt3DCore::QAttribute::defaultPositionAttributeName() );
91
92 Qt3DCore::QAttribute *indexAttribute = new Qt3DCore::QAttribute( parent );
93 indexAttribute->setAttributeType( Qt3DCore::QAttribute::IndexAttribute );
94 indexAttribute->setBuffer( indexBuffer );
95 indexAttribute->setByteOffset( 0 );
96 indexAttribute->setByteStride( sizeof( uint ) );
97 indexAttribute->setVertexBaseType( Qt3DCore::QAttribute::UnsignedInt );
98
99 Qt3DCore::QGeometry *geom = new Qt3DCore::QGeometry;
100 geom->addAttribute( positionAttribute );
101 geom->addAttribute( indexAttribute );
102
103 return geom;
104}
105
106void QgsLineVertexData::addLineString( const QgsLineString &lineString, float extraHeightOffset, bool closePolygon )
107{
108 if ( withAdjacency )
109 indexes << vertices.count(); // add the following vertex (for adjacency)
110
111 QgsPoint centroid;
112 switch ( altBinding )
113 {
115 break;
117 centroid = lineString.centroid();
118 break;
119 }
120
121 const int firstIndex = vertices.count();
122
123 for ( int i = 0; i < lineString.vertexCount(); ++i )
124 {
125 QgsPoint p = lineString.pointN( i );
126 if ( geocentricCoordinates )
127 {
128 // TODO: implement altitude clamping when dealing with geocentric coordinates
129 // where Z coordinate is not altitude and can't be used directly...
130 vertices << QVector3D( static_cast<float>( p.x() - origin.x() ), static_cast<float>( p.y() - origin.y() ), static_cast<float>( p.z() - origin.z() ) );
131 }
132 else
133 {
134 const float z = Qgs3DUtils::clampAltitude( p, altClamping, altBinding, baseHeight + extraHeightOffset, centroid, renderContext );
135 vertices << QVector3D( static_cast<float>( p.x() - origin.x() ), static_cast<float>( p.y() - origin.y() ), static_cast<float>( z - origin.z() ) );
136 }
137 indexes << vertices.count() - 1;
138 }
139
140 if ( closePolygon )
141 indexes << firstIndex; // repeat the first vertex
142
143 if ( withAdjacency )
144 indexes << vertices.count() - 1; // add the last vertex (for adjacency)
145
146 indexes << 0; // add primitive restart
147}
148
149void QgsLineVertexData::addVerticalLines( const QgsLineString &lineString, float verticalLength, float extraHeightOffset )
150{
151 QgsPoint centroid;
152 switch ( altBinding )
153 {
155 break;
157 centroid = lineString.centroid();
158 break;
159 }
160
161 for ( int i = 0; i < lineString.vertexCount(); ++i )
162 {
163 QgsPoint p = lineString.pointN( i );
164 float z = Qgs3DUtils::clampAltitude( p, altClamping, altBinding, baseHeight + extraHeightOffset, centroid, renderContext );
165 float z2 = z + verticalLength;
166
167 if ( withAdjacency )
168 indexes << vertices.count(); // add the following vertex (for adjacency)
169
170 vertices << QVector3D( static_cast<float>( p.x() - origin.x() ), static_cast<float>( p.y() - origin.y() ), z );
171 indexes << vertices.count() - 1;
172 vertices << QVector3D( static_cast<float>( p.x() - origin.x() ), static_cast<float>( p.y() - origin.y() ), z2 );
173 indexes << vertices.count() - 1;
174
175 if ( withAdjacency )
176 indexes << vertices.count() - 1; // add the last vertex (for adjacency)
177
178 indexes << 0; // add primitive restart
179 }
180}
181
182
AltitudeClamping
Altitude clamping.
Definition qgis.h:4041
AltitudeBinding
Altitude binding.
Definition qgis.h:4054
@ Centroid
Clamp just centroid of feature.
Definition qgis.h:4056
@ Vertex
Clamp every vertex of feature.
Definition qgis.h:4055
Rendering context for preparation of 3D entities.
static float clampAltitude(const QgsPoint &p, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const QgsPoint &centroid, const Qgs3DRenderContext &context)
Clamps altitude of a vertex according to the settings, returns Z value.
int vertexCount(int part=0, int ring=0) const override
Returns the number of vertices of which this geometry is built.
Definition qgscurve.cpp:181
Line string geometry type, with support for z-dimension and m-values.
QgsPoint pointN(int i) const
Returns the specified point from inside the line string.
QgsPoint centroid() const override
Returns the centroid of the geometry.
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:53
double z
Definition qgspoint.h:58
double x
Definition qgspoint.h:56
double y
Definition qgspoint.h:57
A 3D vector (similar to QVector3D) with the difference that it uses double precision instead of singl...
Definition qgsvector3d.h:33
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:63