QGIS API Documentation 3.99.0-Master (a5475b57e34)
Loading...
Searching...
No Matches
qgstessellatedpolygongeometry.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgstessellatedpolygongeometry.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
17
18#include "qgstessellator.h"
19
20#include <Qt3DCore/QAttribute>
21#include <Qt3DCore/QBuffer>
22
23#include "moc_qgstessellatedpolygongeometry.cpp"
24
25QgsTessellatedPolygonGeometry::QgsTessellatedPolygonGeometry( bool _withNormals, bool _invertNormals, bool _addBackFaces, bool _addTextureCoords, QNode *parent )
26 : QGeometry( parent )
27 , mWithNormals( _withNormals )
28 , mInvertNormals( _invertNormals )
29 , mAddBackFaces( _addBackFaces )
30 , mAddTextureCoords( _addTextureCoords )
31{
32 mVertexBuffer = new Qt3DCore::QBuffer( this );
33 mIndexBuffer = new Qt3DCore::QBuffer( this );
34
35 QgsTessellator tmpTess;
36 tmpTess.setAddNormals( mWithNormals );
37 tmpTess.setAddTextureUVs( mAddTextureCoords );
38 const int stride = tmpTess.stride();
39
40 mPositionAttribute = new Qt3DCore::QAttribute( this );
41 mPositionAttribute->setName( Qt3DCore::QAttribute::defaultPositionAttributeName() );
42 mPositionAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
43 mPositionAttribute->setVertexSize( 3 );
44 mPositionAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
45 mPositionAttribute->setBuffer( mVertexBuffer );
46 mPositionAttribute->setByteStride( stride );
47 mPositionAttribute->setByteOffset( 0 );
48 addAttribute( mPositionAttribute );
49
50 mIndexAttribute = new Qt3DCore::QAttribute( this );
51 mIndexAttribute->setName( "indexBuffer" );
52 mIndexAttribute->setAttributeType( Qt3DCore::QAttribute::IndexAttribute );
53 mIndexAttribute->setVertexBaseType( Qt3DCore::QAttribute::UnsignedInt );
54 mIndexAttribute->setBuffer( mIndexBuffer );
55 addAttribute( mIndexAttribute );
56
57 if ( mWithNormals )
58 {
59 mNormalAttribute = new Qt3DCore::QAttribute( this );
60 mNormalAttribute->setName( Qt3DCore::QAttribute::defaultNormalAttributeName() );
61 mNormalAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
62 mNormalAttribute->setVertexSize( 3 );
63 mNormalAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
64 mNormalAttribute->setBuffer( mVertexBuffer );
65 mNormalAttribute->setByteStride( stride );
66 mNormalAttribute->setByteOffset( 3 * sizeof( float ) );
67 addAttribute( mNormalAttribute );
68 }
69 if ( mAddTextureCoords )
70 {
71 mTextureCoordsAttribute = new Qt3DCore::QAttribute( this );
72 mTextureCoordsAttribute->setName( Qt3DCore::QAttribute::defaultTextureCoordinateAttributeName() );
73 mTextureCoordsAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
74 mTextureCoordsAttribute->setVertexSize( 2 );
75 mTextureCoordsAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
76 mTextureCoordsAttribute->setBuffer( mVertexBuffer );
77 mTextureCoordsAttribute->setByteStride( stride );
78 mTextureCoordsAttribute->setByteOffset( mWithNormals ? 6 * sizeof( float ) : 3 * sizeof( float ) );
79 addAttribute( mTextureCoordsAttribute );
80 }
81}
82
83void QgsTessellatedPolygonGeometry::setVertexBufferData( const QByteArray &vertexBufferData, int vertexCount, const QVector<QgsFeatureId> &triangleIndexFids, const QVector<uint> &triangleIndexStartingIndices )
84{
85 mTriangleIndexStartingIndices = triangleIndexStartingIndices;
86 mTriangleIndexFids = triangleIndexFids;
87
88 mVertexBuffer->setData( vertexBufferData );
89 mPositionAttribute->setCount( vertexCount );
90 if ( mNormalAttribute )
91 mNormalAttribute->setCount( vertexCount );
92 if ( mTextureCoordsAttribute )
93 mTextureCoordsAttribute->setCount( vertexCount );
94}
95
96void QgsTessellatedPolygonGeometry::setIndexBufferData( const QByteArray &indexBufferData, size_t indexCount )
97{
98 mIndexBuffer->setData( indexBufferData );
99 mIndexAttribute->setCount( indexCount );
100}
101
102// run binary search on a sorted array, return index i where data[i] <= v < data[i+1]
103static int binary_search( uint v, const uint *data, int count )
104{
105 int idx0 = 0;
106 int idx1 = count - 1;
107
108 if ( v < data[0] )
109 return -1; // not in the array
110
111 if ( v >= data[count - 1] )
112 return count - 1; // for larger values the last bin is returned
113
114 while ( idx0 != idx1 )
115 {
116 const int idxPivot = ( idx0 + idx1 ) / 2;
117 const uint pivot = data[idxPivot];
118 if ( pivot <= v )
119 {
120 if ( data[idxPivot + 1] > v )
121 return idxPivot; // we're done!
122 else // continue searching values greater than the pivot
123 idx0 = idxPivot;
124 }
125 else // continue searching values lower than the pivot
126 idx1 = idxPivot;
127 }
128 return idx0;
129}
130
131
133{
134 const int i = binary_search( triangleIndex, mTriangleIndexStartingIndices.constData(), mTriangleIndexStartingIndices.count() );
135 return i != -1 ? mTriangleIndexFids[i] : FID_NULL;
136}
void setVertexBufferData(const QByteArray &vertexBufferData, int vertexCount, const QVector< QgsFeatureId > &triangleIndexFids, const QVector< uint > &triangleIndexStartingIndices)
Initializes vertex buffer (and other members) from data that were already tessellated.
QgsFeatureId triangleIndexToFeatureId(uint triangleIndex) const
Returns ID of the feature to which given triangle index belongs (used for picking).
QgsTessellatedPolygonGeometry(bool _withNormals=true, bool invertNormals=false, bool addBackFaces=false, bool addTextureCoords=false, QNode *parent=nullptr)
Constructor.
QVector< uint > triangleIndexStartingIndices() const
Returns triangle index for features. For a feature featureIds()[i], matching triangles start at trian...
void setIndexBufferData(const QByteArray &indexBufferData, size_t indexCount)
Sets index buffer data.
Tessellates polygons into triangles.
int stride() const
Returns size of one vertex entry in bytes.
void setAddTextureUVs(bool addTextureUVs)
Sets whether texture UV coordinates should be added to the output data (true) or not (false).
void setAddNormals(bool addNormals)
Sets whether normals should be added to the output data (true) or not (false).
#define FID_NULL
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features