17#include "moc_qgspointcloud3dsymbol_p.cpp" 
   30#include <Qt3DCore/QEntity> 
   31#include <Qt3DRender/QGeometryRenderer> 
   32#include <Qt3DRender/QParameter> 
   33#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) 
   34#include <Qt3DRender/QAttribute> 
   35#include <Qt3DRender/QBuffer> 
   36#include <Qt3DRender/QGeometry> 
   42#include <Qt3DCore/QAttribute> 
   43#include <Qt3DCore/QBuffer> 
   44#include <Qt3DCore/QGeometry> 
   50#include <Qt3DRender/QTechnique> 
   51#include <Qt3DRender/QShaderProgram> 
   52#include <Qt3DRender/QGraphicsApiFilter> 
   53#include <Qt3DRender/QEffect> 
   57#include <delaunator.hpp> 
   63  double nodeOriginX = bounds.
xMinimum();
 
   64  double nodeOriginY = bounds.
yMinimum();
 
   72    QgsDebugError( QStringLiteral( 
"Error transforming node origin point" ) );
 
   74  return QgsVector3D( nodeOriginX, nodeOriginY, nodeOriginZ );
 
   78QgsPointCloud3DGeometry::QgsPointCloud3DGeometry( Qt3DCore::QNode *parent, 
const QgsPointCloud3DSymbolHandler::PointData &data, 
unsigned int byteStride )
 
   87  , mByteStride( byteStride )
 
   89  if ( !data.triangles.isEmpty() )
 
   92    mTriangleIndexAttribute->setAttributeType( Qt3DQAttribute::IndexAttribute );
 
   93    mTriangleIndexAttribute->setBuffer( mTriangleBuffer );
 
   94    mTriangleIndexAttribute->setVertexBaseType( Qt3DQAttribute::UnsignedInt );
 
   95    mTriangleBuffer->setData( data.triangles );
 
   96    mTriangleIndexAttribute->setCount( data.triangles.size() / 
sizeof( quint32 ) );
 
   97    addAttribute( mTriangleIndexAttribute );
 
  100  if ( !data.normals.isEmpty() )
 
  103    mNormalsAttribute->setName( Qt3DQAttribute::defaultNormalAttributeName() );
 
  104    mNormalsAttribute->setVertexBaseType( Qt3DQAttribute::Float );
 
  105    mNormalsAttribute->setVertexSize( 3 );
 
  106    mNormalsAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
 
  107    mNormalsAttribute->setBuffer( mNormalsBuffer );
 
  108    mNormalsBuffer->setData( data.normals );
 
  109    mNormalsAttribute->setCount( data.normals.size() / ( 3 * 
sizeof( 
float ) ) );
 
  110    addAttribute( mNormalsAttribute );
 
  114QgsSingleColorPointCloud3DGeometry::QgsSingleColorPointCloud3DGeometry( Qt3DCore::QNode *parent, 
const QgsPointCloud3DSymbolHandler::PointData &data, 
unsigned int byteStride )
 
  115  : QgsPointCloud3DGeometry( parent, data, byteStride )
 
  117  mPositionAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
 
  118  mPositionAttribute->setBuffer( mVertexBuffer );
 
  119  mPositionAttribute->setVertexBaseType( Qt3DQAttribute::Float );
 
  120  mPositionAttribute->setVertexSize( 3 );
 
  121  mPositionAttribute->setName( Qt3DQAttribute::defaultPositionAttributeName() );
 
  122  mPositionAttribute->setByteOffset( 0 );
 
  123  mPositionAttribute->setByteStride( mByteStride );
 
  124  addAttribute( mPositionAttribute );
 
  125  makeVertexBuffer( data );
 
  128void QgsSingleColorPointCloud3DGeometry::makeVertexBuffer( 
const QgsPointCloud3DSymbolHandler::PointData &data )
 
  130  QByteArray vertexBufferData;
 
  131  vertexBufferData.resize( data.positions.size() * mByteStride );
 
  132  float *rawVertexArray = 
reinterpret_cast<float *
>( vertexBufferData.data() );
 
  134  for ( 
int i = 0; i < data.positions.size(); ++i )
 
  136    rawVertexArray[idx++] = data.positions.at( i ).x();
 
  137    rawVertexArray[idx++] = data.positions.at( i ).y();
 
  138    rawVertexArray[idx++] = data.positions.at( i ).z();
 
  141  mVertexCount = data.positions.size();
 
  142  mVertexBuffer->setData( vertexBufferData );
 
  145QgsColorRampPointCloud3DGeometry::QgsColorRampPointCloud3DGeometry( Qt3DCore::QNode *parent, 
const QgsPointCloud3DSymbolHandler::PointData &data, 
unsigned int byteStride )
 
  146  : QgsPointCloud3DGeometry( parent, data, byteStride )
 
  148  mPositionAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
 
  149  mPositionAttribute->setBuffer( mVertexBuffer );
 
  150  mPositionAttribute->setVertexBaseType( Qt3DQAttribute::Float );
 
  151  mPositionAttribute->setVertexSize( 3 );
 
  152  mPositionAttribute->setName( Qt3DQAttribute::defaultPositionAttributeName() );
 
  153  mPositionAttribute->setByteOffset( 0 );
 
  154  mPositionAttribute->setByteStride( mByteStride );
 
  155  addAttribute( mPositionAttribute );
 
  156  mParameterAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
 
  157  mParameterAttribute->setBuffer( mVertexBuffer );
 
  158  mParameterAttribute->setVertexBaseType( Qt3DQAttribute::Float );
 
  159  mParameterAttribute->setVertexSize( 1 );
 
  160  mParameterAttribute->setName( 
"vertexParameter" );
 
  161  mParameterAttribute->setByteOffset( 12 );
 
  162  mParameterAttribute->setByteStride( mByteStride );
 
  163  addAttribute( mParameterAttribute );
 
  164  makeVertexBuffer( data );
 
  167void QgsColorRampPointCloud3DGeometry::makeVertexBuffer( 
const QgsPointCloud3DSymbolHandler::PointData &data )
 
  169  QByteArray vertexBufferData;
 
  170  vertexBufferData.resize( data.positions.size() * mByteStride );
 
  171  float *rawVertexArray = 
reinterpret_cast<float *
>( vertexBufferData.data() );
 
  173  Q_ASSERT( data.positions.size() == data.parameter.size() );
 
  174  for ( 
int i = 0; i < data.positions.size(); ++i )
 
  176    rawVertexArray[idx++] = data.positions.at( i ).x();
 
  177    rawVertexArray[idx++] = data.positions.at( i ).y();
 
  178    rawVertexArray[idx++] = data.positions.at( i ).z();
 
  179    rawVertexArray[idx++] = data.parameter.at( i );
 
  182  mVertexCount = data.positions.size();
 
  183  mVertexBuffer->setData( vertexBufferData );
 
  186QgsRGBPointCloud3DGeometry::QgsRGBPointCloud3DGeometry( Qt3DCore::QNode *parent, 
const QgsPointCloud3DSymbolHandler::PointData &data, 
unsigned int byteStride )
 
  187  : QgsPointCloud3DGeometry( parent, data, byteStride )
 
  189  mPositionAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
 
  190  mPositionAttribute->setBuffer( mVertexBuffer );
 
  191  mPositionAttribute->setVertexBaseType( Qt3DQAttribute::Float );
 
  192  mPositionAttribute->setVertexSize( 3 );
 
  193  mPositionAttribute->setName( Qt3DQAttribute::defaultPositionAttributeName() );
 
  194  mPositionAttribute->setByteOffset( 0 );
 
  195  mPositionAttribute->setByteStride( mByteStride );
 
  196  addAttribute( mPositionAttribute );
 
  197  mColorAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
 
  198  mColorAttribute->setBuffer( mVertexBuffer );
 
  199  mColorAttribute->setVertexBaseType( Qt3DQAttribute::Float );
 
  200  mColorAttribute->setVertexSize( 3 );
 
  201  mColorAttribute->setName( QStringLiteral( 
"vertexColor" ) );
 
  202  mColorAttribute->setByteOffset( 12 );
 
  203  mColorAttribute->setByteStride( mByteStride );
 
  204  addAttribute( mColorAttribute );
 
  205  makeVertexBuffer( data );
 
  208void QgsRGBPointCloud3DGeometry::makeVertexBuffer( 
const QgsPointCloud3DSymbolHandler::PointData &data )
 
  210  QByteArray vertexBufferData;
 
  211  vertexBufferData.resize( data.positions.size() * mByteStride );
 
  212  float *rawVertexArray = 
reinterpret_cast<float *
>( vertexBufferData.data() );
 
  214  Q_ASSERT( data.positions.size() == data.colors.size() );
 
  215  for ( 
int i = 0; i < data.positions.size(); ++i )
 
  217    rawVertexArray[idx++] = data.positions.at( i ).x();
 
  218    rawVertexArray[idx++] = data.positions.at( i ).y();
 
  219    rawVertexArray[idx++] = data.positions.at( i ).z();
 
  220    rawVertexArray[idx++] = data.colors.at( i ).x();
 
  221    rawVertexArray[idx++] = data.colors.at( i ).y();
 
  222    rawVertexArray[idx++] = data.colors.at( i ).z();
 
  224  mVertexCount = data.positions.size();
 
  225  mVertexBuffer->setData( vertexBufferData );
 
  228QgsClassificationPointCloud3DGeometry::QgsClassificationPointCloud3DGeometry( Qt3DCore::QNode *parent, 
const QgsPointCloud3DSymbolHandler::PointData &data, 
unsigned int byteStride )
 
  229  : QgsPointCloud3DGeometry( parent, data, byteStride )
 
  231  mPositionAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
 
  232  mPositionAttribute->setBuffer( mVertexBuffer );
 
  233  mPositionAttribute->setVertexBaseType( Qt3DQAttribute::Float );
 
  234  mPositionAttribute->setVertexSize( 3 );
 
  235  mPositionAttribute->setName( Qt3DQAttribute::defaultPositionAttributeName() );
 
  236  mPositionAttribute->setByteOffset( 0 );
 
  237  mPositionAttribute->setByteStride( mByteStride );
 
  238  addAttribute( mPositionAttribute );
 
  239  mParameterAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
 
  240  mParameterAttribute->setBuffer( mVertexBuffer );
 
  241  mParameterAttribute->setVertexBaseType( Qt3DQAttribute::Float );
 
  242  mParameterAttribute->setVertexSize( 1 );
 
  243  mParameterAttribute->setName( 
"vertexParameter" );
 
  244  mParameterAttribute->setByteOffset( 12 );
 
  245  mParameterAttribute->setByteStride( mByteStride );
 
  246  addAttribute( mParameterAttribute );
 
  247  mPointSizeAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
 
  248  mPointSizeAttribute->setBuffer( mVertexBuffer );
 
  249  mPointSizeAttribute->setVertexBaseType( Qt3DQAttribute::Float );
 
  250  mPointSizeAttribute->setVertexSize( 1 );
 
  251  mPointSizeAttribute->setName( 
"vertexSize" );
 
  252  mPointSizeAttribute->setByteOffset( 16 );
 
  253  mPointSizeAttribute->setByteStride( mByteStride );
 
  254  addAttribute( mPointSizeAttribute );
 
  255  makeVertexBuffer( data );
 
  258void QgsClassificationPointCloud3DGeometry::makeVertexBuffer( 
const QgsPointCloud3DSymbolHandler::PointData &data )
 
  260  QByteArray vertexBufferData;
 
  261  vertexBufferData.resize( data.positions.size() * mByteStride );
 
  262  float *rawVertexArray = 
reinterpret_cast<float *
>( vertexBufferData.data() );
 
  264  Q_ASSERT( data.positions.size() == data.parameter.size() );
 
  265  Q_ASSERT( data.positions.size() == data.pointSizes.size() );
 
  266  for ( 
int i = 0; i < data.positions.size(); ++i )
 
  268    rawVertexArray[idx++] = data.positions.at( i ).x();
 
  269    rawVertexArray[idx++] = data.positions.at( i ).y();
 
  270    rawVertexArray[idx++] = data.positions.at( i ).z();
 
  271    rawVertexArray[idx++] = data.parameter.at( i );
 
  272    rawVertexArray[idx++] = data.pointSizes.at( i );
 
  275  mVertexCount = data.positions.size();
 
  276  mVertexBuffer->setData( vertexBufferData );
 
  279QgsPointCloud3DSymbolHandler::QgsPointCloud3DSymbolHandler()
 
  284void QgsPointCloud3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, 
const QgsPointCloud3DRenderContext &context, 
const QgsPointCloud3DSymbolHandler::PointData &out, 
bool selected )
 
  288  if ( out.positions.empty() )
 
  293  Qt3DRender::QGeometryRenderer *gr = 
new Qt3DRender::QGeometryRenderer;
 
  296    gr->setPrimitiveType( Qt3DRender::QGeometryRenderer::Triangles );
 
  297    gr->setVertexCount( out.triangles.size() / 
sizeof( quint32 ) );
 
  301    gr->setPrimitiveType( Qt3DRender::QGeometryRenderer::Points );
 
  302    gr->setVertexCount( out.positions.count() );
 
  304  gr->setGeometry( geom );
 
  308  QgsGeoTransform *tr = 
new QgsGeoTransform;
 
  309  tr->setGeoTranslation( out.positionsOrigin );
 
  316  Qt3DRender::QShaderProgram *shaderProgram = 
new Qt3DRender::QShaderProgram( mat );
 
  317  shaderProgram->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( 
"qrc:/shaders/pointcloud.vert" ) ) ) );
 
  318  shaderProgram->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( 
"qrc:/shaders/pointcloud.frag" ) ) ) );
 
  320  Qt3DRender::QRenderPass *renderPass = 
new Qt3DRender::QRenderPass( mat );
 
  321  renderPass->setShaderProgram( shaderProgram );
 
  323  if ( out.triangles.isEmpty() )
 
  325    Qt3DRender::QPointSize *pointSize = 
new Qt3DRender::QPointSize( renderPass );
 
  326    pointSize->setSizeMode( Qt3DRender::QPointSize::Programmable ); 
 
  327    renderPass->addRenderState( pointSize );
 
  331  Qt3DRender::QFilterKey *filterKey = 
new Qt3DRender::QFilterKey;
 
  332  filterKey->setName( QStringLiteral( 
"renderingStyle" ) );
 
  333  filterKey->setValue( 
"forward" );
 
  335  Qt3DRender::QTechnique *technique = 
new Qt3DRender::QTechnique;
 
  336  technique->addRenderPass( renderPass );
 
  337  technique->addFilterKey( filterKey );
 
  338  technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
 
  339  technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
 
  340  technique->graphicsApiFilter()->setMajorVersion( 3 );
 
  341  technique->graphicsApiFilter()->setMinorVersion( 1 );
 
  342  technique->addParameter( 
new Qt3DRender::QParameter( 
"triangulate", !out.triangles.isEmpty() ) );
 
  344  Qt3DRender::QEffect *eff = 
new Qt3DRender::QEffect;
 
  345  eff->addTechnique( technique );
 
  346  mat->setEffect( eff );
 
  349  Qt3DCore::QEntity *entity = 
new Qt3DCore::QEntity;
 
  350  entity->addComponent( gr );
 
  351  entity->addComponent( tr );
 
  352  entity->addComponent( mat );
 
  353  entity->setParent( parent );
 
  361  bool hasColorData = !outNormal.colors.empty();
 
  362  bool hasParameterData = !outNormal.parameter.empty();
 
  363  bool hasPointSizeData = !outNormal.pointSizes.empty();
 
  366  std::vector<double> vertices( outNormal.positions.size() * 2 );
 
  368  for ( 
int i = 0; i < outNormal.positions.size(); ++i )
 
  370    vertices[idx++] = outNormal.positions.at( i ).x();
 
  371    vertices[idx++] = -outNormal.positions.at( i ).y(); 
 
  377  double span = pc.
span();
 
  380  double extraBoxFactor = 16 / span;
 
  383  QgsRectangle rectRelativeToChunkOrigin = ( box3D - outNormal.positionsOrigin ).toRectangle();
 
  384  rectRelativeToChunkOrigin.
grow( extraBoxFactor * std::max( box3D.
width(), box3D.
height() ) );
 
  386  PointData filteredExtraPointData;
 
  387  while ( parentNode.
d() >= 0 )
 
  389    PointData outputParent;
 
  390    processNode( pc, parentNode, context, &outputParent );
 
  393    QVector3D originDifference = ( outputParent.positionsOrigin - outNormal.positionsOrigin ).toVector3D();
 
  395    for ( 
int i = 0; i < outputParent.positions.count(); ++i )
 
  397      const QVector3D pos = outputParent.positions.at( i ) + originDifference;
 
  398      if ( rectRelativeToChunkOrigin.
contains( pos.x(), pos.y() ) )
 
  400        filteredExtraPointData.positions.append( pos );
 
  401        vertices.push_back( pos.x() );
 
  402        vertices.push_back( -pos.y() ); 
 
  405          filteredExtraPointData.colors.append( outputParent.colors.at( i ) );
 
  406        if ( hasParameterData )
 
  407          filteredExtraPointData.parameter.append( outputParent.parameter.at( i ) );
 
  408        if ( hasPointSizeData )
 
  409          filteredExtraPointData.pointSizes.append( outputParent.pointSizes.at( i ) );
 
  416  outNormal.positions.append( filteredExtraPointData.positions );
 
  417  outNormal.colors.append( filteredExtraPointData.colors );
 
  418  outNormal.parameter.append( filteredExtraPointData.parameter );
 
  419  outNormal.pointSizes.append( filteredExtraPointData.pointSizes );
 
  424void QgsPointCloud3DSymbolHandler::calculateNormals( 
const std::vector<size_t> &triangles )
 
  426  QVector<QVector3D> normals( outNormal.positions.count(), QVector3D( 0.0, 0.0, 0.0 ) );
 
  427  for ( 
size_t i = 0; i < triangles.size(); i += 3 )
 
  429    QVector<QVector3D> triangleVertices( 3 );
 
  430    for ( 
size_t j = 0; j < 3; ++j )
 
  432      size_t vertIndex = triangles.at( i + j );
 
  433      triangleVertices[j] = outNormal.positions.at( vertIndex );
 
  436    for ( 
size_t j = 0; j < 3; ++j )
 
  437      normals[triangles.at( i + j )] += QVector3D::crossProduct(
 
  438        triangleVertices.at( 1 ) - triangleVertices.at( 0 ),
 
  439        triangleVertices.at( 2 ) - triangleVertices.at( 0 )
 
  444  outNormal.normals.resize( ( outNormal.positions.count() ) * 
sizeof( 
float ) * 3 );
 
  445  float *normPtr = 
reinterpret_cast<float *
>( outNormal.normals.data() );
 
  446  for ( 
int i = 0; i < normals.size(); ++i )
 
  448    QVector3D normal = normals.at( i );
 
  449    normal = normal.normalized();
 
  451    *normPtr++ = normal.x();
 
  452    *normPtr++ = normal.y();
 
  453    *normPtr++ = normal.z();
 
  459  outNormal.triangles.resize( triangleIndexes.size() * 
sizeof( quint32 ) );
 
  460  quint32 *indexPtr = 
reinterpret_cast<quint32 *
>( outNormal.triangles.data() );
 
  461  size_t effective = 0;
 
  468  QgsBox3D boxRelativeToChunkOrigin = box3D - outNormal.positionsOrigin;
 
  470  for ( 
size_t i = 0; i < triangleIndexes.size(); i += 3 )
 
  472    bool atLeastOneInBox = 
false;
 
  473    bool horizontalSkip = 
false;
 
  474    bool verticalSkip = 
false;
 
  475    for ( 
size_t j = 0; j < 3; j++ )
 
  477      QVector3D pos = outNormal.positions.at( triangleIndexes.at( i + j ) );
 
  478      atLeastOneInBox |= boxRelativeToChunkOrigin.
contains( pos.x(), pos.y(), pos.z() );
 
  480      if ( verticalFilter || horizontalFilter )
 
  482        const QVector3D pos2 = outNormal.positions.at( triangleIndexes.at( i + ( j + 1 ) % 3 ) );
 
  484        if ( verticalFilter )
 
  485          verticalSkip |= std::fabs( pos.z() - pos2.z() ) > verticalThreshold;
 
  487        if ( horizontalFilter && !verticalSkip )
 
  490          horizontalSkip |= sqrt( std::pow( pos.x() - pos2.x(), 2 ) + std::pow( pos.y() - pos2.y(), 2 ) ) > horizontalThreshold;
 
  493        if ( horizontalSkip || verticalSkip )
 
  497    if ( atLeastOneInBox && !horizontalSkip && !verticalSkip )
 
  499      for ( 
size_t j = 0; j < 3; j++ )
 
  501        size_t vertIndex = triangleIndexes.at( i + j );
 
  502        *indexPtr++ = quint32( vertIndex );
 
  508  if ( effective != 0 )
 
  510    outNormal.triangles.resize( effective * 3 * 
sizeof( quint32 ) );
 
  514    outNormal.triangles.clear();
 
  515    outNormal.normals.clear();
 
  521  if ( outNormal.positions.isEmpty() )
 
  525  std::unique_ptr<delaunator::Delaunator> triangulation;
 
  528    std::vector<double> vertices = getVertices( pc, n, context, box3D );
 
  529    triangulation.reset( 
new delaunator::Delaunator( vertices ) );
 
  531  catch ( std::exception &e )
 
  535    outNormal = PointData();
 
  536    processNode( pc, n, context );
 
  540  const std::vector<size_t> &triangleIndexes = triangulation->triangles;
 
  542  calculateNormals( triangleIndexes );
 
  543  filterTriangles( triangleIndexes, context, box3D );
 
  548  std::unique_ptr<QgsPointCloudBlock> block;
 
  559    bool loopAborted = 
false;
 
  577QgsSingleColorPointCloud3DSymbolHandler::QgsSingleColorPointCloud3DSymbolHandler()
 
  578  : QgsPointCloud3DSymbolHandler()
 
  598  std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
 
  602  const char *ptr = block->data();
 
  603  const int count = block->pointCount();
 
  604  const std::size_t recordSize = block->attributes().pointRecordSize();
 
  610  bool alreadyPrintedDebug = 
false;
 
  615  output->positionsOrigin = originFromNodeBounds( pc, n, context );
 
  617  for ( 
int i = 0; i < count; ++i )
 
  622    const qint32 ix = *( qint32 * ) ( ptr + i * recordSize + 0 );
 
  623    const qint32 iy = *( qint32 * ) ( ptr + i * recordSize + 4 );
 
  624    const qint32 iz = *( qint32 * ) ( ptr + i * recordSize + 8 );
 
  626    double x = blockOffset.
x() + blockScale.
x() * ix;
 
  627    double y = blockOffset.
y() + blockScale.
y() * iy;
 
  628    double z = ( blockOffset.
z() + blockScale.
z() * iz ) * zValueScale + zValueOffset;
 
  635      if ( !alreadyPrintedDebug )
 
  637        QgsDebugError( QStringLiteral( 
"Error transforming point coordinate" ) );
 
  638        alreadyPrintedDebug = 
true;
 
  642    output->positions.push_back( point.
toVector3D() );
 
  648  makeEntity( parent, context, outNormal, 
false );
 
  651Qt3DQGeometry *QgsSingleColorPointCloud3DSymbolHandler::makeGeometry( Qt3DCore::QNode *parent, 
const QgsPointCloud3DSymbolHandler::PointData &data, 
unsigned int byteStride )
 
  653  return new QgsSingleColorPointCloud3DGeometry( parent, data, byteStride );
 
  656QgsColorRampPointCloud3DSymbolHandler::QgsColorRampPointCloud3DSymbolHandler()
 
  657  : QgsPointCloud3DSymbolHandler()
 
  670  const int xOffset = 0;
 
  677  QString attributeName;
 
  678  bool attrIsX = 
false;
 
  679  bool attrIsY = 
false;
 
  680  bool attrIsZ = 
false;
 
  682  int attributeOffset = 0;
 
  686  bool alreadyPrintedDebug = 
false;
 
  694    if ( symbol->
attribute() == QLatin1String( 
"X" ) )
 
  698    else if ( symbol->
attribute() == QLatin1String( 
"Y" ) )
 
  702    else if ( symbol->
attribute() == QLatin1String( 
"Z" ) )
 
  711        attributeType = attr->
type();
 
  712        attributeName = attr->
name();
 
  719  if ( attributeName.isEmpty() && !attrIsX && !attrIsY && !attrIsZ )
 
  725  std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
 
  729  const char *ptr = block->data();
 
  730  const int count = block->pointCount();
 
  731  const std::size_t recordSize = block->attributes().pointRecordSize();
 
  739  output->positionsOrigin = originFromNodeBounds( pc, n, context );
 
  741  for ( 
int i = 0; i < count; ++i )
 
  746    const qint32 ix = *( qint32 * ) ( ptr + i * recordSize + xOffset );
 
  747    const qint32 iy = *( qint32 * ) ( ptr + i * recordSize + yOffset );
 
  748    const qint32 iz = *( qint32 * ) ( ptr + i * recordSize + zOffset );
 
  750    double x = blockOffset.
x() + blockScale.
x() * ix;
 
  751    double y = blockOffset.
y() + blockScale.
y() * iy;
 
  752    double z = ( blockOffset.
z() + blockScale.
z() * iz ) * zValueScale + zValueOffset;
 
  759      if ( !alreadyPrintedDebug )
 
  761        QgsDebugError( QStringLiteral( 
"Error transforming point coordinate" ) );
 
  762        alreadyPrintedDebug = 
true;
 
  766    output->positions.push_back( point.
toVector3D() );
 
  769      output->parameter.push_back( x );
 
  771      output->parameter.push_back( y );
 
  773      output->parameter.push_back( z );
 
  777      context.
getAttribute( ptr, i * recordSize + attributeOffset, attributeType, iParam );
 
  778      output->parameter.push_back( iParam );
 
  785  makeEntity( parent, context, outNormal, 
false );
 
  788Qt3DQGeometry *QgsColorRampPointCloud3DSymbolHandler::makeGeometry( Qt3DCore::QNode *parent, 
const QgsPointCloud3DSymbolHandler::PointData &data, 
unsigned int byteStride )
 
  790  return new QgsColorRampPointCloud3DGeometry( parent, data, byteStride );
 
  793QgsRGBPointCloud3DSymbolHandler::QgsRGBPointCloud3DSymbolHandler()
 
  794  : QgsPointCloud3DSymbolHandler()
 
  834  std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
 
  838  const char *ptr = block->data();
 
  839  const int count = block->pointCount();
 
  840  const std::size_t recordSize = block->attributes().pointRecordSize();
 
  847  bool alreadyPrintedDebug = 
false;
 
  860  output->positionsOrigin = originFromNodeBounds( pc, n, context );
 
  865  for ( 
int i = 0; i < count; ++i )
 
  870    const qint32 ix = *( qint32 * ) ( ptr + i * recordSize + 0 );
 
  871    const qint32 iy = *( qint32 * ) ( ptr + i * recordSize + 4 );
 
  872    const qint32 iz = *( qint32 * ) ( ptr + i * recordSize + 8 );
 
  873    double x = blockOffset.
x() + blockScale.
x() * ix;
 
  874    double y = blockOffset.
y() + blockScale.
y() * iy;
 
  875    double z = ( blockOffset.
z() + blockScale.
z() * iz ) * zValueScale + zValueOffset;
 
  882      if ( !alreadyPrintedDebug )
 
  884        QgsDebugError( QStringLiteral( 
"Error transforming point coordinate" ) );
 
  885        alreadyPrintedDebug = 
true;
 
  890    QVector3D color( 0.0f, 0.0f, 0.0f );
 
  892    context.
getAttribute( ptr, i * recordSize + redOffset, redType, ir );
 
  893    context.
getAttribute( ptr, i * recordSize + greenOffset, greenType, ig );
 
  894    context.
getAttribute( ptr, i * recordSize + blueOffset, blueType, ib );
 
  905    if ( useRedContrastEnhancement )
 
  909    if ( useGreenContrastEnhancement )
 
  913    if ( useBlueContrastEnhancement )
 
  918    color.setX( ir / 255.0f );
 
  919    color.setY( ig / 255.0f );
 
  920    color.setZ( ib / 255.0f );
 
  922    output->positions.push_back( point.
toVector3D() );
 
  923    output->colors.push_back( color );
 
  929  makeEntity( parent, context, outNormal, 
false );
 
  932Qt3DQGeometry *QgsRGBPointCloud3DSymbolHandler::makeGeometry( Qt3DCore::QNode *parent, 
const QgsPointCloud3DSymbolHandler::PointData &data, 
unsigned int byteStride )
 
  934  return new QgsRGBPointCloud3DGeometry( parent, data, byteStride );
 
  937QgsClassificationPointCloud3DSymbolHandler::QgsClassificationPointCloud3DSymbolHandler()
 
  938  : QgsPointCloud3DSymbolHandler()
 
  951  const int xOffset = 0;
 
  958  QString attributeName;
 
  959  bool attrIsX = 
false;
 
  960  bool attrIsY = 
false;
 
  961  bool attrIsZ = 
false;
 
  963  int attributeOffset = 0;
 
  971  if ( symbol->
attribute() == QLatin1String( 
"X" ) )
 
  975  else if ( symbol->
attribute() == QLatin1String( 
"Y" ) )
 
  979  else if ( symbol->
attribute() == QLatin1String( 
"Z" ) )
 
  988      attributeType = attr->
type();
 
  989      attributeName = attr->
name();
 
  995  if ( attributeName.isEmpty() && !attrIsX && !attrIsY && !attrIsZ )
 
 1001  std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
 
 1005  const char *ptr = block->data();
 
 1006  const int count = block->pointCount();
 
 1007  const std::size_t recordSize = block->attributes().pointRecordSize();
 
 1014  bool alreadyPrintedDebug = 
false;
 
 1016  QList<QgsPointCloudCategory> categoriesList = symbol->
categoriesList();
 
 1017  QVector<int> categoriesValues;
 
 1018  QHash<int, double> categoriesPointSizes;
 
 1021    categoriesValues.push_back( 
c.value() );
 
 1022    categoriesPointSizes.insert( 
c.value(), 
c.pointSize() > 0 ? 
c.pointSize() : context.symbol() ? context.symbol()->pointSize()
 
 1027    output = &outNormal;
 
 1029  output->positionsOrigin = originFromNodeBounds( pc, n, context );
 
 1032  for ( 
int i = 0; i < count; ++i )
 
 1037    const qint32 ix = *( qint32 * ) ( ptr + i * recordSize + xOffset );
 
 1038    const qint32 iy = *( qint32 * ) ( ptr + i * recordSize + yOffset );
 
 1039    const qint32 iz = *( qint32 * ) ( ptr + i * recordSize + zOffset );
 
 1041    double x = blockOffset.
x() + blockScale.
x() * ix;
 
 1042    double y = blockOffset.
y() + blockScale.
y() * iy;
 
 1043    double z = ( blockOffset.
z() + blockScale.
z() * iz ) * zValueScale + zValueOffset;
 
 1050      if ( !alreadyPrintedDebug )
 
 1052        QgsDebugError( QStringLiteral( 
"Error transforming point coordinate" ) );
 
 1053        alreadyPrintedDebug = 
true;
 
 1057    float iParam = 0.0f;
 
 1065      context.
getAttribute( ptr, i * recordSize + attributeOffset, attributeType, iParam );
 
 1067    if ( filteredOutValues.contains( ( 
int ) iParam ) || !categoriesValues.contains( ( 
int ) iParam ) )
 
 1069    output->positions.push_back( point.
toVector3D() );
 
 1072    float iParam2 = categoriesValues.indexOf( ( 
int ) iParam ) + 1;
 
 1073    output->parameter.push_back( iParam2 );
 
 1074    output->pointSizes.push_back( categoriesPointSizes.value( ( 
int ) iParam ) );
 
 1080  makeEntity( parent, context, outNormal, 
false );
 
 1083Qt3DQGeometry *QgsClassificationPointCloud3DSymbolHandler::makeGeometry( Qt3DCore::QNode *parent, 
const QgsPointCloud3DSymbolHandler::PointData &data, 
unsigned int byteStride )
 
 1085  return new QgsClassificationPointCloud3DGeometry( parent, data, byteStride );
 
@ Local
Local means the source is a local file on the machine.
 
@ Remote
Remote means it's loaded through a protocol like HTTP.
 
A 3-dimensional box composed of x, y, z coordinates.
 
double xMinimum() const
Returns the minimum x value.
 
bool contains(const QgsBox3D &other) const
Returns true when box contains other box.
 
double width() const
Returns the width of the box.
 
double zMinimum() const
Returns the minimum z value.
 
double yMinimum() const
Returns the minimum y value.
 
double height() const
Returns the height of the box.
 
3D symbol that draws point cloud geometries as 3D objects using classification of the dataset.
 
QgsPointCloudCategoryList categoriesList() const
Returns the list of categories of the classification.
 
QString attribute() const
Returns the attribute used to select the color of the point cloud.
 
3D symbol that draws point cloud geometries as 3D objects using color ramp shader.
 
QString attribute() const
Returns the attribute used to select the color of the point cloud.
 
Handles contrast enhancement and clipping.
 
@ NoEnhancement
Default color scaling algorithm, no scaling is applied.
 
bool isValueInDisplayableRange(double value)
Returns true if a pixel value is in displayable range, false if pixel is outside of range (i....
 
int enhanceContrast(double value)
Applies the contrast enhancement to a value.
 
ContrastEnhancementAlgorithm contrastEnhancementAlgorithm() const
 
Custom exception class for Coordinate Reference System related exceptions.
 
void canceled()
Internal routines can connect to this signal if they use event loop.
 
Base class for all materials used within QGIS 3D views.
 
Encapsulates the render context for a 3D point cloud rendering operation.
 
void getAttribute(const char *data, std::size_t offset, QgsPointCloudAttribute::DataType type, T &value) const
Retrieves the attribute value from data at the specified offset, where type indicates the original da...
 
QSet< int > getFilteredOutValues() const
Returns a set containing the filtered out values.
 
QgsPointCloud3DSymbol * symbol() const
Returns the symbol used for rendering the point cloud.
 
double zValueScale() const
Returns any constant scaling factor which must be applied to z values taken from the point cloud inde...
 
QgsFeedback * feedback() const
Returns the feedback object used to cancel rendering and check if rendering was canceled.
 
QgsPointCloudAttributeCollection attributes() const
Returns the attributes associated with the rendered block.
 
bool isCanceled() const
Returns true if the rendering is canceled.
 
QgsCoordinateTransform coordinateTransform() const
Returns the coordinate transform used to transform points from layer CRS to the map CRS.
 
QgsRectangle layerExtent() const
Returns the 3D scene's extent in layer crs.
 
double zValueFixedOffset() const
Returns any constant offset which must be applied to z values taken from the point cloud index.
 
bool verticalTriangleFilter() const
Returns whether triangles are filtered by vertical height for rendering.
 
float verticalFilterThreshold() const
Returns the threshold vertical height value for filtering triangles.
 
virtual void fillMaterial(QgsMaterial *material)=0SIP_SKIP
Used to fill material object with necessary QParameters (and consequently opengl uniforms)
 
virtual unsigned int byteStride()=0
Returns the byte stride for the geometries used to for the vertex buffer.
 
float horizontalFilterThreshold() const
Returns the threshold horizontal size value for filtering triangles.
 
bool renderAsTriangles() const
Returns whether points are triangulated to render solid surface.
 
bool horizontalTriangleFilter() const
Returns whether triangles are filtered by horizontal size for rendering.
 
A collection of point cloud attributes.
 
void push_back(const QgsPointCloudAttribute &attribute)
Adds extra attribute.
 
int pointRecordSize() const
Returns total size of record.
 
const QgsPointCloudAttribute * find(const QString &attributeName, int &offset) const
Finds the attribute with the name.
 
Attribute for point cloud data pair of name and size in bytes.
 
DataType
Systems of unit measurement.
 
QString name() const
Returns name of the attribute.
 
DataType type() const
Returns the data type.
 
Base class for handling loading QgsPointCloudBlock asynchronously.
 
void finished()
Emitted when the request processing has finished.
 
std::unique_ptr< QgsPointCloudBlock > takeBlock()
Returns the requested block.
 
Represents an individual category (class) from a QgsPointCloudClassifiedRenderer.
 
Smart pointer for QgsAbstractPointCloudIndex.
 
int span() const
Returns the number of points in one direction in a single node.
 
QgsPointCloudBlockRequest * asyncNodeData(const QgsPointCloudNodeId &n, const QgsPointCloudRequest &request)
Returns a handle responsible for loading a node data block.
 
std::unique_ptr< QgsPointCloudBlock > nodeData(const QgsPointCloudNodeId &n, const QgsPointCloudRequest &request)
Returns node data block.
 
QgsPointCloudNode getNode(const QgsPointCloudNodeId &id) const
Returns object for a given node.
 
Qgis::PointCloudAccessType accessType() const
Returns the access type of the data If the access type is Remote, data will be fetched from an HTTP s...
 
Represents an indexed point cloud node's position in octree.
 
QgsPointCloudNodeId parentNode() const
Returns the parent of the node.
 
Keeps metadata for an indexed point cloud node.
 
qint64 pointCount() const
Returns number of points contained in node data.
 
QgsBox3D bounds() const
Returns node's bounding cube in CRS coords.
 
Point cloud data request.
 
void setFilterRect(QgsRectangle extent)
Sets the rectangle from which points will be taken, in point cloud's crs.
 
void setAttributes(const QgsPointCloudAttributeCollection &attributes)
Set attributes filter in the request.
 
A rectangle specified with double values.
 
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
 
void grow(double delta)
Grows the rectangle in place by the specified amount.
 
3D symbol that draws point cloud geometries as 3D objects using RGB colors in the dataset.
 
QString blueAttribute() const
Returns the attribute to use for the blue channel.
 
QString greenAttribute() const
Returns the attribute to use for the green channel.
 
QgsContrastEnhancement * blueContrastEnhancement()
Returns the contrast enhancement to use for the blue channel.
 
QString redAttribute() const
Returns the attribute to use for the red channel.
 
QgsContrastEnhancement * greenContrastEnhancement()
Returns the contrast enhancement to use for the green channel.
 
QgsContrastEnhancement * redContrastEnhancement()
Returns the contrast enhancement to use for the red channel.
 
A 3D vector (similar to QVector3D) with the difference that it uses double precision instead of singl...
 
double y() const
Returns Y coordinate.
 
double z() const
Returns Z coordinate.
 
QVector3D toVector3D() const
Converts the current object to QVector3D.
 
double x() const
Returns X coordinate.
 
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
 
Qt3DCore::QAttribute Qt3DQAttribute
 
Qt3DCore::QBuffer Qt3DQBuffer
 
Qt3DCore::QGeometry Qt3DQGeometry
 
#define QgsDebugMsgLevel(str, level)
 
#define QgsDebugError(str)