QGIS API Documentation 3.99.0-Master (e9821da5c6b)
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 "qgsmessagelog.h"
19#include "qgspolygon.h"
20#include "qgstessellator.h"
21
22#include <QMatrix4x4>
23#include <Qt3DCore/QAttribute>
24#include <Qt3DCore/QBuffer>
25
26#include "moc_qgstessellatedpolygongeometry.cpp"
27
28QgsTessellatedPolygonGeometry::QgsTessellatedPolygonGeometry( bool _withNormals, bool _invertNormals, bool _addBackFaces, bool _addTextureCoords, QNode *parent )
29 : QGeometry( parent )
30 , mWithNormals( _withNormals )
31 , mInvertNormals( _invertNormals )
32 , mAddBackFaces( _addBackFaces )
33 , mAddTextureCoords( _addTextureCoords )
34{
35 mVertexBuffer = new Qt3DCore::QBuffer( this );
36
37 QgsTessellator tmpTess;
38 tmpTess.setAddNormals( mWithNormals );
39 tmpTess.setAddTextureUVs( mAddTextureCoords );
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
52 if ( mWithNormals )
53 {
54 mNormalAttribute = new Qt3DCore::QAttribute( this );
55 mNormalAttribute->setName( Qt3DCore::QAttribute::defaultNormalAttributeName() );
56 mNormalAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
57 mNormalAttribute->setVertexSize( 3 );
58 mNormalAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
59 mNormalAttribute->setBuffer( mVertexBuffer );
60 mNormalAttribute->setByteStride( stride );
61 mNormalAttribute->setByteOffset( 3 * sizeof( float ) );
62 addAttribute( mNormalAttribute );
63 }
64 if ( mAddTextureCoords )
65 {
66 mTextureCoordsAttribute = new Qt3DCore::QAttribute( this );
67 mTextureCoordsAttribute->setName( Qt3DCore::QAttribute::defaultTextureCoordinateAttributeName() );
68 mTextureCoordsAttribute->setVertexBaseType( Qt3DCore::QAttribute::Float );
69 mTextureCoordsAttribute->setVertexSize( 2 );
70 mTextureCoordsAttribute->setAttributeType( Qt3DCore::QAttribute::VertexAttribute );
71 mTextureCoordsAttribute->setBuffer( mVertexBuffer );
72 mTextureCoordsAttribute->setByteStride( stride );
73 mTextureCoordsAttribute->setByteOffset( mWithNormals ? 6 * sizeof( float ) : 3 * sizeof( float ) );
74 addAttribute( mTextureCoordsAttribute );
75 }
76}
77
78void QgsTessellatedPolygonGeometry::setData( const QByteArray &vertexBufferData, int vertexCount, const QVector<QgsFeatureId> &triangleIndexFids, const QVector<uint> &triangleIndexStartingIndices )
79{
80 mTriangleIndexStartingIndices = triangleIndexStartingIndices;
81 mTriangleIndexFids = triangleIndexFids;
82
83 mVertexBuffer->setData( vertexBufferData );
84 mPositionAttribute->setCount( vertexCount );
85 if ( mNormalAttribute )
86 mNormalAttribute->setCount( vertexCount );
87 if ( mTextureCoordsAttribute )
88 mTextureCoordsAttribute->setCount( vertexCount );
89}
90
91// run binary search on a sorted array, return index i where data[i] <= v < data[i+1]
92static int binary_search( uint v, const uint *data, int count )
93{
94 int idx0 = 0;
95 int idx1 = count - 1;
96
97 if ( v < data[0] )
98 return -1; // not in the array
99
100 if ( v >= data[count - 1] )
101 return count - 1; // for larger values the last bin is returned
102
103 while ( idx0 != idx1 )
104 {
105 const int idxPivot = ( idx0 + idx1 ) / 2;
106 const uint pivot = data[idxPivot];
107 if ( pivot <= v )
108 {
109 if ( data[idxPivot + 1] > v )
110 return idxPivot; // we're done!
111 else // continue searching values greater than the pivot
112 idx0 = idxPivot;
113 }
114 else // continue searching values lower than the pivot
115 idx1 = idxPivot;
116 }
117 return idx0;
118}
119
120
122{
123 const int i = binary_search( triangleIndex, mTriangleIndexStartingIndices.constData(), mTriangleIndexStartingIndices.count() );
124 return i != -1 ? mTriangleIndexFids[i] : FID_NULL;
125}
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.
void setData(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.
QVector< uint > triangleIndexStartingIndices() const
Returns triangle index for features. For a feature featureIds()[i], matching triangles start at trian...
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