18 #include <Qt3DRender/QAttribute>
19 #include <Qt3DRender/QBuffer>
20 #include <Qt3DRender/QBufferDataGenerator>
30 mWithNormals( _withNormals ),
31 mInvertNormals( _invertNormals ),
32 mAddBackFaces( _addBackFaces ),
33 mAddTextureCoords( _addTextureCoords )
35 #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
36 mVertexBuffer =
new Qt3DRender::QBuffer( Qt3DRender::QBuffer::VertexBuffer,
this );
38 mVertexBuffer =
new Qt3DRender::QBuffer(
this );
41 QgsTessellator tmpTess( 0, 0, mWithNormals,
false,
false,
false, mAddTextureCoords );
42 const int stride = tmpTess.
stride();
44 mPositionAttribute =
new Qt3DRender::QAttribute(
this );
45 mPositionAttribute->setName( Qt3DRender::QAttribute::defaultPositionAttributeName() );
46 mPositionAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
47 mPositionAttribute->setVertexSize( 3 );
48 mPositionAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
49 mPositionAttribute->setBuffer( mVertexBuffer );
50 mPositionAttribute->setByteStride( stride );
51 mPositionAttribute->setByteOffset( 0 );
52 addAttribute( mPositionAttribute );
56 mNormalAttribute =
new Qt3DRender::QAttribute(
this );
57 mNormalAttribute->setName( Qt3DRender::QAttribute::defaultNormalAttributeName() );
58 mNormalAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
59 mNormalAttribute->setVertexSize( 3 );
60 mNormalAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
61 mNormalAttribute->setBuffer( mVertexBuffer );
62 mNormalAttribute->setByteStride( stride );
63 mNormalAttribute->setByteOffset( 3 *
sizeof(
float ) );
64 addAttribute( mNormalAttribute );
66 if ( mAddTextureCoords )
68 mTextureCoordsAttribute =
new Qt3DRender::QAttribute(
this );
69 mTextureCoordsAttribute->setName( Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName() );
70 mTextureCoordsAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
71 mTextureCoordsAttribute->setVertexSize( 2 );
72 mTextureCoordsAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
73 mTextureCoordsAttribute->setBuffer( mVertexBuffer );
74 mTextureCoordsAttribute->setByteStride( stride );
75 mTextureCoordsAttribute->setByteOffset( mWithNormals ? 6 *
sizeof(
float ) : 3 *
sizeof(
float ) );
76 addAttribute( mTextureCoordsAttribute );
82 Q_ASSERT( polygons.count() == featureIds.count() );
83 mTriangleIndexStartingIndices.reserve( polygons.count() );
84 mTriangleIndexFids.reserve( polygons.count() );
86 QgsTessellator tessellator( origin.
x(), origin.
y(), mWithNormals, mInvertNormals, mAddBackFaces,
false, mAddTextureCoords );
87 for (
int i = 0; i < polygons.count(); ++i )
90 uint startingTriangleIndex =
static_cast<uint
>( tessellator.
dataVerticesCount() / 3 );
91 mTriangleIndexStartingIndices.append( startingTriangleIndex );
92 mTriangleIndexFids.append( featureIds[i] );
95 float extr = extrusionHeightPerPolygon.
isEmpty() ? extrusionHeight : extrusionHeightPerPolygon.at( i );
99 qDeleteAll( polygons );
101 QByteArray data( (
const char * )tessellator.
data().constData(), tessellator.
data().count() *
sizeof(
float ) );
102 int nVerts = data.count() / tessellator.
stride();
104 mVertexBuffer->setData( data );
105 mPositionAttribute->setCount( nVerts );
106 if ( mNormalAttribute )
107 mNormalAttribute->setCount( nVerts );
108 if ( mAddTextureCoords )
109 mTextureCoordsAttribute->setCount( nVerts );
114 mTriangleIndexStartingIndices = triangleIndexStartingIndices;
115 mTriangleIndexFids = triangleIndexFids;
117 mVertexBuffer->setData( vertexBufferData );
118 mPositionAttribute->setCount( vertexCount );
119 if ( mNormalAttribute )
120 mNormalAttribute->setCount( vertexCount );
121 if ( mTextureCoordsAttribute )
122 mTextureCoordsAttribute->setCount( vertexCount );
127 static int binary_search( uint v,
const uint *data,
int count )
130 int idx1 = count - 1;
132 if ( v < data[0] || v >= data[count - 1] )
135 while ( idx0 != idx1 )
137 int idxPivot = ( idx0 + idx1 ) / 2;
138 uint pivot = data[idxPivot];
141 if ( data[idxPivot + 1] > v )
155 int i = binary_search( triangleIndex, mTriangleIndexStartingIndices.constData(), mTriangleIndexStartingIndices.count() );
156 return i != -1 ? mTriangleIndexFids[i] :
FID_NULL;
bool isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
A class to represent a 2D point.
void setPolygons(const QList< QgsPolygon * > &polygons, const QList< QgsFeatureId > &featureIds, const QgsPointXY &origin, float extrusionHeight, const QList< float > &extrusionHeightPerPolygon=QList< float >())
Initializes vertex buffer from given polygons. Takes ownership of passed polygon geometries.
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.
Class that takes care of tessellation of polygons into triangles.
QVector< float > data() const
Returns array of triangle vertex data.
int stride() const
Returns size of one vertex entry in bytes.
void addPolygon(const QgsPolygon &polygon, float extrusionHeight)
Tessellates a triangle and adds its vertex entries to the output data array.
int dataVerticesCount() const
Returns the number of vertices stored in the output data array.
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features