20#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 
   21#include <Qt3DRender/QAttribute> 
   22#include <Qt3DRender/QBuffer> 
   26#include <Qt3DCore/QAttribute> 
   27#include <Qt3DCore/QBuffer> 
   37  , mWithNormals( _withNormals )
 
   38  , mInvertNormals( _invertNormals )
 
   39  , mAddBackFaces( _addBackFaces )
 
   40  , mAddTextureCoords( _addTextureCoords )
 
   44  const QgsTessellator tmpTess( 0, 0, mWithNormals, 
false, 
false, 
false, mAddTextureCoords );
 
   45  const int stride = tmpTess.
stride();
 
   48  mPositionAttribute->setName( Qt3DQAttribute::defaultPositionAttributeName() );
 
   49  mPositionAttribute->setVertexBaseType( Qt3DQAttribute::Float );
 
   50  mPositionAttribute->setVertexSize( 3 );
 
   51  mPositionAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
 
   52  mPositionAttribute->setBuffer( mVertexBuffer );
 
   53  mPositionAttribute->setByteStride( stride );
 
   54  mPositionAttribute->setByteOffset( 0 );
 
   55  addAttribute( mPositionAttribute );
 
   60    mNormalAttribute->setName( Qt3DQAttribute::defaultNormalAttributeName() );
 
   61    mNormalAttribute->setVertexBaseType( Qt3DQAttribute::Float );
 
   62    mNormalAttribute->setVertexSize( 3 );
 
   63    mNormalAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
 
   64    mNormalAttribute->setBuffer( mVertexBuffer );
 
   65    mNormalAttribute->setByteStride( stride );
 
   66    mNormalAttribute->setByteOffset( 3 * 
sizeof( 
float ) );
 
   67    addAttribute( mNormalAttribute );
 
   69  if ( mAddTextureCoords )
 
   72    mTextureCoordsAttribute->setName( Qt3DQAttribute::defaultTextureCoordinateAttributeName() );
 
   73    mTextureCoordsAttribute->setVertexBaseType( Qt3DQAttribute::Float );
 
   74    mTextureCoordsAttribute->setVertexSize( 2 );
 
   75    mTextureCoordsAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
 
   76    mTextureCoordsAttribute->setBuffer( mVertexBuffer );
 
   77    mTextureCoordsAttribute->setByteStride( stride );
 
   78    mTextureCoordsAttribute->setByteOffset( mWithNormals ? 6 * 
sizeof( 
float ) : 3 * 
sizeof( 
float ) );
 
   79    addAttribute( mTextureCoordsAttribute );
 
   83static bool intersectionTriangles( 
const QByteArray &vertexBuf, 
const int &stride, 
const QgsRayCastingUtils::Ray3D &r, 
const QMatrix4x4 &worldTransform, QVector3D &intPt, 
int &triangleIndex )
 
   85  const float *vertices = 
reinterpret_cast<const float *
>( vertexBuf.constData() );
 
   87  const int vertexCount = vertexBuf.size() / stride;
 
   88  const int triangleCount = vertexCount / 3;
 
   90  QVector3D intersectionPt, minIntersectionPt;
 
   91  float minDistance = -1;
 
   93  const int vertexSize = stride / 
sizeof( float );
 
   94  const int triangleSize = 3 * vertexSize;
 
   95  for ( 
int i = 0; i < triangleCount; ++i )
 
   97    const int v0 = i * triangleSize, v1 = i * triangleSize + vertexSize, v2 = i * triangleSize + vertexSize + vertexSize;
 
   99    const QVector3D a( vertices[v0], vertices[v0 + 1], vertices[v0 + 2] );
 
  100    const QVector3D b( vertices[v1], vertices[v1 + 1], vertices[v1 + 2] );
 
  101    const QVector3D 
c( vertices[v2], vertices[v2 + 1], vertices[v2 + 2] );
 
  106    const QVector3D tA = worldTransform * a;
 
  107    const QVector3D tB = worldTransform * b;
 
  108    const QVector3D tC = worldTransform * 
c;
 
  116    if ( QgsRayCastingUtils::rayTriangleIntersection( r, tA, tB, tC, uvw, t ) ||
 
  117         QgsRayCastingUtils::rayTriangleIntersection( r, tA, tC, tB, uvw, t ) )
 
  119      intersectionPt = r.point( t * r.distance() );
 
  120      const float distance = r.projectedDistance( intersectionPt );
 
  123      if ( minDistance == -1 || distance < minDistance )
 
  125        triangleIndex = 
static_cast<int>( i );
 
  126        minDistance = distance;
 
  127        minIntersectionPt = intersectionPt;
 
  132  if ( minDistance != -1 )
 
  134    intPt = minIntersectionPt;
 
  143  Q_ASSERT( polygons.count() == featureIds.count() );
 
  144  mTriangleIndexStartingIndices.reserve( polygons.count() );
 
  145  mTriangleIndexFids.reserve( polygons.count() );
 
  147  QgsTessellator tessellator( origin.
x(), origin.
y(), mWithNormals, mInvertNormals, mAddBackFaces, 
false, mAddTextureCoords );
 
  148  for ( 
int i = 0; i < polygons.count(); ++i )
 
  151    const uint startingTriangleIndex = 
static_cast<uint
>( tessellator.
dataVerticesCount() / 3 );
 
  152    mTriangleIndexStartingIndices.append( startingTriangleIndex );
 
  153    mTriangleIndexFids.append( featureIds[i] );
 
  156    const float extr = extrusionHeightPerPolygon.
isEmpty() ? extrusionHeight : extrusionHeightPerPolygon.at( i );
 
  160  qDeleteAll( polygons );
 
  162  const QByteArray data( ( 
const char * )tessellator.
data().constData(), tessellator.
data().count() * 
sizeof( 
float ) );
 
  163  const int nVerts = data.count() / tessellator.
stride();
 
  165  mVertexBuffer->setData( data );
 
  166  mPositionAttribute->setCount( nVerts );
 
  167  if ( mNormalAttribute )
 
  168    mNormalAttribute->setCount( nVerts );
 
  169  if ( mAddTextureCoords )
 
  170    mTextureCoordsAttribute->setCount( nVerts );
 
  175  mTriangleIndexStartingIndices = triangleIndexStartingIndices;
 
  176  mTriangleIndexFids = triangleIndexFids;
 
  178  mVertexBuffer->setData( vertexBufferData );
 
  179  mPositionAttribute->setCount( vertexCount );
 
  180  if ( mNormalAttribute )
 
  181    mNormalAttribute->setCount( vertexCount );
 
  182  if ( mTextureCoordsAttribute )
 
  183    mTextureCoordsAttribute->setCount( vertexCount );
 
  188  int triangleIndex = -1;
 
  189  const int stride = 
static_cast<int>( mPositionAttribute->byteStride() );
 
  190  bool success = intersectionTriangles( mVertexBuffer->data(), stride, ray, worldTransform, intersectionPoint, triangleIndex );
 
  198static int binary_search( uint v, 
const uint *data, 
int count )
 
  201  int idx1 = count - 1;
 
  206  if ( v >= data[count - 1] )
 
  209  while ( idx0 != idx1 )
 
  211    const int idxPivot = ( idx0 + idx1 ) / 2;
 
  212    const uint pivot = data[idxPivot];
 
  215      if ( data[idxPivot + 1] > v )
 
  229  const int i = binary_search( triangleIndex, mTriangleIndexStartingIndices.constData(), mTriangleIndexStartingIndices.count() );
 
  230  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.
 
bool rayIntersection(const QgsRayCastingUtils::Ray3D &ray, const QMatrix4x4 &worldTransform, QVector3D &intersectionPoint, QgsFeatureId &fid)
Tests whether the geometry is intersected by ray.
 
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.
 
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
 
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
 
Qt3DCore::QAttribute Qt3DQAttribute
 
Qt3DCore::QBuffer Qt3DQBuffer