QGIS API Documentation 4.1.0-Master (01362494303)
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, bool withTangents, QNode *parent )
26 : QGeometry( parent )
27 , mWithNormals( _withNormals )
28 , mInvertNormals( _invertNormals )
29 , mAddBackFaces( _addBackFaces )
30 , mAddTextureCoords( _addTextureCoords )
31 , mWithTangents( withTangents )
32{
33 mVertexBuffer = new Qt3DCore::QBuffer( this );
34 mIndexBuffer = new Qt3DCore::QBuffer( this );
35
36 QgsTessellator tmpTess;
37 tmpTess.setAddNormals( mWithNormals );
38 tmpTess.setAddTextureUVs( mAddTextureCoords );
39 tmpTess.setAddTangents( mWithTangents );
40 const int stride = tmpTess.stride();
41
42 mPositionAttribute = new Qt3DCore::QAttribute( this );
43 mPositionAttribute->setName( Qt3DCore::QAttribute::defaultPositionAttributeName() );
44 mPositionAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
45 mPositionAttribute->setVertexSize( 3 );
46 mPositionAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
47 mPositionAttribute->setBuffer( mVertexBuffer );
48 mPositionAttribute->setByteStride( stride );
49 mPositionAttribute->setByteOffset( 0 );
50 addAttribute( mPositionAttribute );
51 int vertexBufferOffset = 3 * sizeof( float );
52
53 mIndexAttribute = new Qt3DCore::QAttribute( this );
54 mIndexAttribute->setName( "indexBuffer" );
55 mIndexAttribute->setAttributeType( Qt3DCore::QAttribute::IndexAttribute );
56 mIndexAttribute->setVertexBaseType( Qt3DCore::QAttribute::UnsignedInt );
57 mIndexAttribute->setBuffer( mIndexBuffer );
58 addAttribute( mIndexAttribute );
59
60 if ( mWithNormals )
61 {
62 mNormalAttribute = new Qt3DCore::QAttribute( this );
63 mNormalAttribute->setName( Qt3DCore::QAttribute::defaultNormalAttributeName() );
64 mNormalAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
65 mNormalAttribute->setVertexSize( 3 );
66 mNormalAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
67 mNormalAttribute->setBuffer( mVertexBuffer );
68 mNormalAttribute->setByteStride( stride );
69 mNormalAttribute->setByteOffset( vertexBufferOffset );
70 addAttribute( mNormalAttribute );
71 vertexBufferOffset += 3 * sizeof( float );
72 }
73 if ( mWithTangents )
74 {
75 mTangentAttribute = new Qt3DCore::QAttribute( this );
76 mTangentAttribute->setName( Qt3DCore::QAttribute::defaultTangentAttributeName() ); // "vertexTangent"
77 mTangentAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
78 mTangentAttribute->setVertexSize( 4 );
79 mTangentAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
80 mTangentAttribute->setBuffer( mVertexBuffer );
81 mTangentAttribute->setByteStride( stride );
82 mTangentAttribute->setByteOffset( vertexBufferOffset );
83 addAttribute( mTangentAttribute );
84 vertexBufferOffset += 4 * sizeof( float );
85 }
86 if ( mAddTextureCoords )
87 {
88 mTextureCoordsAttribute = new Qt3DCore::QAttribute( this );
89 mTextureCoordsAttribute->setName( Qt3DCore::QAttribute::defaultTextureCoordinateAttributeName() );
90 mTextureCoordsAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
91 mTextureCoordsAttribute->setVertexSize( 2 );
92 mTextureCoordsAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
93 mTextureCoordsAttribute->setBuffer( mVertexBuffer );
94 mTextureCoordsAttribute->setByteStride( stride );
95 mTextureCoordsAttribute->setByteOffset( vertexBufferOffset );
96 addAttribute( mTextureCoordsAttribute );
97 vertexBufferOffset += 2 * sizeof( float );
98 }
99}
100
101void QgsTessellatedPolygonGeometry::setVertexBufferData( const QByteArray &vertexBufferData, int vertexCount, const QVector<QgsFeatureId> &triangleIndexFids, const QVector<uint> &triangleIndexStartingIndices )
102{
103 mTriangleIndexStartingIndices = triangleIndexStartingIndices;
104 mTriangleIndexFids = triangleIndexFids;
105
106 mVertexBuffer->setData( vertexBufferData );
107 mPositionAttribute->setCount( vertexCount );
108 if ( mNormalAttribute )
109 mNormalAttribute->setCount( vertexCount );
110 if ( mTangentAttribute )
111 mTangentAttribute->setCount( vertexCount );
112 if ( mTextureCoordsAttribute )
113 mTextureCoordsAttribute->setCount( vertexCount );
114}
115
116void QgsTessellatedPolygonGeometry::setIndexBufferData( const QByteArray &indexBufferData, size_t indexCount )
117{
118 mIndexBuffer->setData( indexBufferData );
119 mIndexAttribute->setCount( indexCount );
120}
121
122// run binary search on a sorted array, return index i where data[i] <= v < data[i+1]
123static int binary_search( uint v, const uint *data, int count )
124{
125 int idx0 = 0;
126 int idx1 = count - 1;
127
128 if ( v < data[0] )
129 return -1; // not in the array
130
131 if ( v >= data[count - 1] )
132 return count - 1; // for larger values the last bin is returned
133
134 while ( idx0 != idx1 )
135 {
136 const int idxPivot = ( idx0 + idx1 ) / 2;
137 const uint pivot = data[idxPivot];
138 if ( pivot <= v )
139 {
140 if ( data[idxPivot + 1] > v )
141 return idxPivot; // we're done!
142 else // continue searching values greater than the pivot
143 idx0 = idxPivot;
144 }
145 else // continue searching values lower than the pivot
146 idx1 = idxPivot;
147 }
148 return idx0;
149}
150
151
153{
154 const int i = binary_search( triangleIndex, mTriangleIndexStartingIndices.constData(), mTriangleIndexStartingIndices.count() );
155 return i != -1 ? mTriangleIndexFids[i] : FID_NULL;
156}
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.
QgsTessellatedPolygonGeometry(bool _withNormals=true, bool invertNormals=false, bool addBackFaces=false, bool addTextureCoords=false, bool withTangents=false, QNode *parent=nullptr)
Constructor.
QgsFeatureId triangleIndexToFeatureId(uint triangleIndex) const
Returns ID of the feature to which given triangle index belongs (used for picking).
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 setAddTangents(bool addTangents)
Sets whether tangents should be added to the output data.
void setAddTextureUVs(bool addTextureUVs)
Sets whether texture UV coordinates should be added to the output data.
void setAddNormals(bool addNormals)
Sets whether normals should be added to the output data.
#define FID_NULL
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features