28#include <Qt3DRender/QGeometryRenderer>
29#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
30#include <Qt3DRender/QAttribute>
31#include <Qt3DRender/QBuffer>
32#include <Qt3DRender/QGeometry>
38#include <Qt3DCore/QAttribute>
39#include <Qt3DCore/QBuffer>
40#include <Qt3DCore/QGeometry>
46#include <Qt3DRender/QTechnique>
47#include <Qt3DRender/QShaderProgram>
48#include <Qt3DRender/QGraphicsApiFilter>
49#include <Qt3DRender/QEffect>
53#include <delaunator.hpp>
55QgsPointCloud3DGeometry::QgsPointCloud3DGeometry( Qt3DCore::QNode *parent,
const QgsPointCloud3DSymbolHandler::PointData &data,
unsigned int byteStride )
63 , mByteStride( byteStride )
65 if ( !data.triangles.isEmpty() )
68 mTriangleIndexAttribute->setAttributeType( Qt3DQAttribute::IndexAttribute );
69 mTriangleIndexAttribute->setBuffer( mTriangleBuffer );
70 mTriangleIndexAttribute->setVertexBaseType( Qt3DQAttribute::UnsignedInt );
71 mTriangleBuffer->setData( data.triangles );
72 mTriangleIndexAttribute->setCount( data.triangles.size() /
sizeof( quint32 ) );
73 addAttribute( mTriangleIndexAttribute );
76 if ( !data.normals.isEmpty() )
79 mNormalsAttribute->setName( Qt3DQAttribute::defaultNormalAttributeName() );
80 mNormalsAttribute->setVertexBaseType( Qt3DQAttribute::Float );
81 mNormalsAttribute->setVertexSize( 3 );
82 mNormalsAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
83 mNormalsAttribute->setBuffer( mNormalsBuffer );
84 mNormalsBuffer->setData( data.normals );
85 mNormalsAttribute->setCount( data.normals.size() / ( 3 *
sizeof(
float ) ) );
86 addAttribute( mNormalsAttribute );
90QgsSingleColorPointCloud3DGeometry::QgsSingleColorPointCloud3DGeometry( Qt3DCore::QNode *parent,
const QgsPointCloud3DSymbolHandler::PointData &data,
unsigned int byteStride )
91 : QgsPointCloud3DGeometry( parent, data, byteStride )
93 mPositionAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
94 mPositionAttribute->setBuffer( mVertexBuffer );
95 mPositionAttribute->setVertexBaseType( Qt3DQAttribute::Float );
96 mPositionAttribute->setVertexSize( 3 );
97 mPositionAttribute->setName( Qt3DQAttribute::defaultPositionAttributeName() );
98 mPositionAttribute->setByteOffset( 0 );
99 mPositionAttribute->setByteStride( mByteStride );
100 addAttribute( mPositionAttribute );
101 makeVertexBuffer( data );
104void QgsSingleColorPointCloud3DGeometry::makeVertexBuffer(
const QgsPointCloud3DSymbolHandler::PointData &data )
106 QByteArray vertexBufferData;
107 vertexBufferData.resize( data.positions.size() * mByteStride );
108 float *rawVertexArray =
reinterpret_cast<float *
>( vertexBufferData.data() );
110 for (
int i = 0; i < data.positions.size(); ++i )
112 rawVertexArray[idx++] = data.positions.at( i ).x();
113 rawVertexArray[idx++] = data.positions.at( i ).y();
114 rawVertexArray[idx++] = data.positions.at( i ).z();
117 mVertexCount = data.positions.size();
118 mVertexBuffer->setData( vertexBufferData );
121QgsColorRampPointCloud3DGeometry::QgsColorRampPointCloud3DGeometry( Qt3DCore::QNode *parent,
const QgsPointCloud3DSymbolHandler::PointData &data,
unsigned int byteStride )
122 : QgsPointCloud3DGeometry( parent, data, byteStride )
124 mPositionAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
125 mPositionAttribute->setBuffer( mVertexBuffer );
126 mPositionAttribute->setVertexBaseType( Qt3DQAttribute::Float );
127 mPositionAttribute->setVertexSize( 3 );
128 mPositionAttribute->setName( Qt3DQAttribute::defaultPositionAttributeName() );
129 mPositionAttribute->setByteOffset( 0 );
130 mPositionAttribute->setByteStride( mByteStride );
131 addAttribute( mPositionAttribute );
132 mParameterAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
133 mParameterAttribute->setBuffer( mVertexBuffer );
134 mParameterAttribute->setVertexBaseType( Qt3DQAttribute::Float );
135 mParameterAttribute->setVertexSize( 1 );
136 mParameterAttribute->setName(
"vertexParameter" );
137 mParameterAttribute->setByteOffset( 12 );
138 mParameterAttribute->setByteStride( mByteStride );
139 addAttribute( mParameterAttribute );
140 makeVertexBuffer( data );
143void QgsColorRampPointCloud3DGeometry::makeVertexBuffer(
const QgsPointCloud3DSymbolHandler::PointData &data )
145 QByteArray vertexBufferData;
146 vertexBufferData.resize( data.positions.size() * mByteStride );
147 float *rawVertexArray =
reinterpret_cast<float *
>( vertexBufferData.data() );
149 Q_ASSERT( data.positions.size() == data.parameter.size() );
150 for (
int i = 0; i < data.positions.size(); ++i )
152 rawVertexArray[idx++] = data.positions.at( i ).x();
153 rawVertexArray[idx++] = data.positions.at( i ).y();
154 rawVertexArray[idx++] = data.positions.at( i ).z();
155 rawVertexArray[idx++] = data.parameter.at( i );
158 mVertexCount = data.positions.size();
159 mVertexBuffer->setData( vertexBufferData );
162QgsRGBPointCloud3DGeometry::QgsRGBPointCloud3DGeometry( Qt3DCore::QNode *parent,
const QgsPointCloud3DSymbolHandler::PointData &data,
unsigned int byteStride )
163 : QgsPointCloud3DGeometry( parent, data, byteStride )
165 mPositionAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
166 mPositionAttribute->setBuffer( mVertexBuffer );
167 mPositionAttribute->setVertexBaseType( Qt3DQAttribute::Float );
168 mPositionAttribute->setVertexSize( 3 );
169 mPositionAttribute->setName( Qt3DQAttribute::defaultPositionAttributeName() );
170 mPositionAttribute->setByteOffset( 0 );
171 mPositionAttribute->setByteStride( mByteStride );
172 addAttribute( mPositionAttribute );
173 mColorAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
174 mColorAttribute->setBuffer( mVertexBuffer );
175 mColorAttribute->setVertexBaseType( Qt3DQAttribute::Float );
176 mColorAttribute->setVertexSize( 3 );
177 mColorAttribute->setName( QStringLiteral(
"vertexColor" ) );
178 mColorAttribute->setByteOffset( 12 );
179 mColorAttribute->setByteStride( mByteStride );
180 addAttribute( mColorAttribute );
181 makeVertexBuffer( data );
184void QgsRGBPointCloud3DGeometry::makeVertexBuffer(
const QgsPointCloud3DSymbolHandler::PointData &data )
186 QByteArray vertexBufferData;
187 vertexBufferData.resize( data.positions.size() * mByteStride );
188 float *rawVertexArray =
reinterpret_cast<float *
>( vertexBufferData.data() );
190 Q_ASSERT( data.positions.size() == data.colors.size() );
191 for (
int i = 0; i < data.positions.size(); ++i )
193 rawVertexArray[idx++] = data.positions.at( i ).x();
194 rawVertexArray[idx++] = data.positions.at( i ).y();
195 rawVertexArray[idx++] = data.positions.at( i ).z();
196 rawVertexArray[idx++] = data.colors.at( i ).x();
197 rawVertexArray[idx++] = data.colors.at( i ).y();
198 rawVertexArray[idx++] = data.colors.at( i ).z();
200 mVertexCount = data.positions.size();
201 mVertexBuffer->setData( vertexBufferData );
204QgsPointCloud3DSymbolHandler::QgsPointCloud3DSymbolHandler()
209void QgsPointCloud3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent,
const QgsPointCloud3DRenderContext &context,
const QgsPointCloud3DSymbolHandler::PointData &out,
bool selected )
213 if ( out.positions.empty() )
218 Qt3DRender::QGeometryRenderer *gr =
new Qt3DRender::QGeometryRenderer;
221 gr->setPrimitiveType( Qt3DRender::QGeometryRenderer::Triangles );
222 gr->setVertexCount( out.triangles.size() /
sizeof( quint32 ) );
226 gr->setPrimitiveType( Qt3DRender::QGeometryRenderer::Points );
227 gr->setVertexCount( out.positions.count() );
229 gr->setGeometry( geom );
232 Qt3DCore::QTransform *tr =
new Qt3DCore::QTransform;
235 Qt3DRender::QMaterial *mat =
new Qt3DRender::QMaterial;
239 Qt3DRender::QShaderProgram *shaderProgram =
new Qt3DRender::QShaderProgram( mat );
240 shaderProgram->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral(
"qrc:/shaders/pointcloud.vert" ) ) ) );
241 shaderProgram->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral(
"qrc:/shaders/pointcloud.frag" ) ) ) );
243 Qt3DRender::QRenderPass *renderPass =
new Qt3DRender::QRenderPass( mat );
244 renderPass->setShaderProgram( shaderProgram );
246 if ( out.triangles.isEmpty() )
248 Qt3DRender::QPointSize *pointSize =
new Qt3DRender::QPointSize( renderPass );
249 pointSize->setSizeMode( Qt3DRender::QPointSize::Programmable );
251 renderPass->addRenderState( pointSize );
255 Qt3DRender::QFilterKey *filterKey =
new Qt3DRender::QFilterKey;
256 filterKey->setName( QStringLiteral(
"renderingStyle" ) );
257 filterKey->setValue(
"forward" );
259 Qt3DRender::QTechnique *technique =
new Qt3DRender::QTechnique;
260 technique->addRenderPass( renderPass );
261 technique->addFilterKey( filterKey );
262 technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
263 technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
264 technique->graphicsApiFilter()->setMajorVersion( 3 );
265 technique->graphicsApiFilter()->setMinorVersion( 1 );
266 technique->addParameter(
new Qt3DRender::QParameter(
"triangulate", !out.triangles.isEmpty() ) );
268 Qt3DRender::QEffect *eff =
new Qt3DRender::QEffect;
269 eff->addTechnique( technique );
270 mat->setEffect( eff );
273 Qt3DCore::QEntity *entity =
new Qt3DCore::QEntity;
274 entity->addComponent( gr );
275 entity->addComponent( tr );
276 entity->addComponent( mat );
277 entity->setParent( parent );
286 bool hasColorData = !outNormal.colors.empty();
287 bool hasParameterData = !outNormal.parameter.empty();
290 std::vector<double> vertices( outNormal.positions.size() * 2 );
292 for (
int i = 0; i < outNormal.positions.size(); ++i )
294 vertices[idx++] = outNormal.positions.at( i ).x();
295 vertices[idx++] = outNormal.positions.at( i ).z();
301 int properPointsCount = outNormal.positions.count();
302 while ( parentNode.
d() >= 0 )
304 processNode( pc, parentNode, context );
308 PointData filteredExtraPointData;
310 double span = pc->
span();
313 double extraBoxFactor = 16 / span;
314 double extraX = extraBoxFactor * bbox.
xExtent();
315 double extraZ = extraBoxFactor * bbox.
zExtent();
318 const QgsAABB extendedBBox( bbox.
xMin - extraX, -std::numeric_limits<float>::max(), bbox.
zMin - extraZ, bbox.
xMax + extraX, std::numeric_limits<float>::max(), bbox.
zMax + extraZ );
320 for (
int i = properPointsCount; i < outNormal.positions.count(); ++i )
322 const QVector3D pos = outNormal.positions.at( i );
323 if ( extendedBBox.intersects( pos.x(), pos.y(), pos.z() ) )
325 filteredExtraPointData.positions.append( pos );
326 vertices.push_back( pos.x() );
327 vertices.push_back( pos.z() );
330 filteredExtraPointData.colors.append( outNormal.colors.at( i ) );
331 if ( hasParameterData )
332 filteredExtraPointData.parameter.append( outNormal.parameter.at( i ) );
336 outNormal.positions.resize( properPointsCount );
338 outNormal.colors.resize( properPointsCount );
339 if ( hasParameterData )
340 outNormal.parameter.resize( properPointsCount );
342 outNormal.positions.append( filteredExtraPointData.positions );
343 outNormal.colors.append( filteredExtraPointData.colors );
344 outNormal.parameter.append( filteredExtraPointData.parameter );
349void QgsPointCloud3DSymbolHandler::calculateNormals(
const std::vector<size_t> &triangles )
351 QVector<QVector3D> normals( outNormal.positions.count(), QVector3D( 0.0, 0.0, 0.0 ) );
352 for (
size_t i = 0; i < triangles.size(); i += 3 )
354 QVector<QVector3D> triangleVertices( 3 );
355 for (
size_t j = 0; j < 3; ++j )
357 size_t vertIndex = triangles.at( i + j );
358 triangleVertices[j] = outNormal.positions.at( vertIndex );
361 for (
size_t j = 0; j < 3; ++j )
362 normals[triangles.at( i + j )] += QVector3D::crossProduct(
363 triangleVertices.at( 1 ) - triangleVertices.at( 0 ),
364 triangleVertices.at( 2 ) - triangleVertices.at( 0 ) );
368 outNormal.normals.resize( ( outNormal.positions.count() ) *
sizeof(
float ) * 3 );
369 float *normPtr =
reinterpret_cast<float *
>( outNormal.normals.data() );
370 for (
int i = 0; i < normals.size(); ++i )
372 QVector3D normal = normals.at( i );
373 normal = normal.normalized();
375 *normPtr++ = normal.x();
376 *normPtr++ = normal.y();
377 *normPtr++ = normal.z();
383 outNormal.triangles.resize( triangleIndexes.size() *
sizeof( quint32 ) );
384 quint32 *indexPtr =
reinterpret_cast<quint32 *
>( outNormal.triangles.data() );
385 size_t effective = 0;
392 for (
size_t i = 0; i < triangleIndexes.size(); i += 3 )
394 bool atLeastOneInBox =
false;
395 bool horizontalSkip =
false;
396 bool verticalSkip =
false;
397 for (
size_t j = 0; j < 3; j++ )
399 QVector3D pos = outNormal.positions.at( triangleIndexes.at( i + j ) );
400 atLeastOneInBox |= bbox.
intersects( pos.x(), pos.y(), pos.z() );
402 if ( verticalFilter || horizontalFilter )
404 const QVector3D pos2 = outNormal.positions.at( triangleIndexes.at( i + ( j + 1 ) % 3 ) );
406 if ( verticalFilter )
407 verticalSkip |= std::fabs( pos.y() - pos2.y() ) > verticalThreshold;
409 if ( horizontalFilter && ! verticalSkip )
412 horizontalSkip |= sqrt( std::pow( pos.x() - pos2.x(), 2 ) +
413 std::pow( pos.z() - pos2.z(), 2 ) ) > horizontalThreshold;
416 if ( horizontalSkip || verticalSkip )
420 if ( atLeastOneInBox && !horizontalSkip && !verticalSkip )
422 for (
size_t j = 0; j < 3; j++ )
424 size_t vertIndex = triangleIndexes.at( i + j );
425 *indexPtr++ = quint32( vertIndex );
431 if ( effective != 0 )
433 outNormal.triangles.resize( effective * 3 *
sizeof( quint32 ) );
437 outNormal.triangles.clear();
438 outNormal.normals.clear();
444 if ( outNormal.positions.isEmpty() )
448 std::unique_ptr<delaunator::Delaunator> triangulation;
451 std::vector<double> vertices = getVertices( pc, n, context, bbox );
452 triangulation.reset(
new delaunator::Delaunator( vertices ) );
454 catch ( std::exception &e )
458 outNormal = PointData();
459 processNode( pc, n, context );
463 const std::vector<size_t> &triangleIndexes = triangulation->triangles;
465 calculateNormals( triangleIndexes );
466 filterTriangles( triangleIndexes, context, bbox );
471 std::unique_ptr<QgsPointCloudBlock> block;
478 bool loopAborted =
false;
497QgsSingleColorPointCloud3DSymbolHandler::QgsSingleColorPointCloud3DSymbolHandler()
498 : QgsPointCloud3DSymbolHandler()
519 std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
523 const char *ptr = block->data();
524 const int count = block->pointCount();
525 const std::size_t recordSize = block->attributes().pointRecordSize();
531 bool alreadyPrintedDebug =
false;
533 for (
int i = 0; i < count; ++i )
538 const qint32 ix = *( qint32 * )( ptr + i * recordSize + 0 );
539 const qint32 iy = *( qint32 * )( ptr + i * recordSize + 4 );
540 const qint32 iz = *( qint32 * )( ptr + i * recordSize + 8 );
542 double x = blockOffset.
x() + blockScale.
x() * ix;
543 double y = blockOffset.
y() + blockScale.
y() * iy;
544 double z = ( blockOffset.
z() + blockScale.
z() * iz ) * zValueScale + zValueOffset;
551 if ( !alreadyPrintedDebug )
553 QgsDebugError( QStringLiteral(
"Error transforming point coordinate" ) );
554 alreadyPrintedDebug =
true;
559 outNormal.positions.push_back( QVector3D( p.
x(), p.
y(), p.
z() ) );
565 makeEntity( parent, context, outNormal,
false );
568Qt3DQGeometry *QgsSingleColorPointCloud3DSymbolHandler::makeGeometry( Qt3DCore::QNode *parent,
const QgsPointCloud3DSymbolHandler::PointData &data,
unsigned int byteStride )
570 return new QgsSingleColorPointCloud3DGeometry( parent, data, byteStride );
573QgsColorRampPointCloud3DSymbolHandler::QgsColorRampPointCloud3DSymbolHandler()
574 : QgsPointCloud3DSymbolHandler()
588 const int xOffset = 0;
595 QString attributeName;
596 bool attrIsX =
false;
597 bool attrIsY =
false;
598 bool attrIsZ =
false;
600 int attributeOffset = 0;
604 bool alreadyPrintedDebug =
false;
612 if ( symbol->
attribute() == QLatin1String(
"X" ) )
616 else if ( symbol->
attribute() == QLatin1String(
"Y" ) )
620 else if ( symbol->
attribute() == QLatin1String(
"Z" ) )
629 attributeType = attr->
type();
630 attributeName = attr->
name();
637 if ( attributeName.isEmpty() && !attrIsX && !attrIsY && !attrIsZ )
643 std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
647 const char *ptr = block->data();
648 const int count = block->pointCount();
649 const std::size_t recordSize = block->attributes().pointRecordSize();
654 for (
int i = 0; i < count; ++i )
659 const qint32 ix = *( qint32 * )( ptr + i * recordSize + xOffset );
660 const qint32 iy = *( qint32 * )( ptr + i * recordSize + yOffset );
661 const qint32 iz = *( qint32 * )( ptr + i * recordSize + zOffset );
663 double x = blockOffset.
x() + blockScale.
x() * ix;
664 double y = blockOffset.
y() + blockScale.
y() * iy;
665 double z = ( blockOffset.
z() + blockScale.
z() * iz ) * zValueScale + zValueOffset;
672 if ( !alreadyPrintedDebug )
674 QgsDebugError( QStringLiteral(
"Error transforming point coordinate" ) );
675 alreadyPrintedDebug =
true;
679 point = context.map().mapToWorldCoordinates( point );
680 outNormal.positions.push_back( QVector3D( point.x(), point.y(), point.z() ) );
683 outNormal.parameter.push_back( x );
685 outNormal.parameter.push_back( y );
687 outNormal.parameter.push_back( z );
691 context.
getAttribute( ptr, i * recordSize + attributeOffset, attributeType, iParam );
692 outNormal.parameter.push_back( iParam );
699 makeEntity( parent, context, outNormal,
false );
702Qt3DQGeometry *QgsColorRampPointCloud3DSymbolHandler::makeGeometry( Qt3DCore::QNode *parent,
const QgsPointCloud3DSymbolHandler::PointData &data,
unsigned int byteStride )
704 return new QgsColorRampPointCloud3DGeometry( parent, data, byteStride );
707QgsRGBPointCloud3DSymbolHandler::QgsRGBPointCloud3DSymbolHandler()
708 : QgsPointCloud3DSymbolHandler()
749 std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
753 const char *ptr = block->data();
754 const int count = block->pointCount();
755 const std::size_t recordSize = block->attributes().pointRecordSize();
762 bool alreadyPrintedDebug =
false;
775 for (
int i = 0; i < count; ++i )
780 const qint32 ix = *( qint32 * )( ptr + i * recordSize + 0 );
781 const qint32 iy = *( qint32 * )( ptr + i * recordSize + 4 );
782 const qint32 iz = *( qint32 * )( ptr + i * recordSize + 8 );
783 double x = blockOffset.
x() + blockScale.
x() * ix;
784 double y = blockOffset.
y() + blockScale.
y() * iy;
785 double z = ( blockOffset.
z() + blockScale.
z() * iz ) * zValueScale + zValueOffset;
792 if ( !alreadyPrintedDebug )
794 QgsDebugError( QStringLiteral(
"Error transforming point coordinate" ) );
795 alreadyPrintedDebug =
true;
799 const QgsVector3D p = context.map().mapToWorldCoordinates( point );
801 QVector3D color( 0.0f, 0.0f, 0.0f );
803 context.
getAttribute( ptr, i * recordSize + redOffset, redType, ir );
804 context.
getAttribute( ptr, i * recordSize + greenOffset, greenType, ig );
805 context.
getAttribute( ptr, i * recordSize + blueOffset, blueType, ib );
816 if ( useRedContrastEnhancement )
820 if ( useGreenContrastEnhancement )
824 if ( useBlueContrastEnhancement )
829 color.setX( ir / 255.0f );
830 color.setY( ig / 255.0f );
831 color.setZ( ib / 255.0f );
833 outNormal.positions.push_back( QVector3D( p.
x(), p.
y(), p.
z() ) );
834 outNormal.colors.push_back( color );
840 makeEntity( parent, context, outNormal,
false );
843Qt3DQGeometry *QgsRGBPointCloud3DSymbolHandler::makeGeometry( Qt3DCore::QNode *parent,
const QgsPointCloud3DSymbolHandler::PointData &data,
unsigned int byteStride )
845 return new QgsRGBPointCloud3DGeometry( parent, data, byteStride );
848QgsClassificationPointCloud3DSymbolHandler::QgsClassificationPointCloud3DSymbolHandler()
849 : QgsPointCloud3DSymbolHandler()
863 const int xOffset = 0;
870 QString attributeName;
871 bool attrIsX =
false;
872 bool attrIsY =
false;
873 bool attrIsZ =
false;
875 int attributeOffset = 0;
882 if ( symbol->
attribute() == QLatin1String(
"X" ) )
886 else if ( symbol->
attribute() == QLatin1String(
"Y" ) )
890 else if ( symbol->
attribute() == QLatin1String(
"Z" ) )
899 attributeType = attr->
type();
900 attributeName = attr->
name();
907 if ( attributeName.isEmpty() && !attrIsX && !attrIsY && !attrIsZ )
913 std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
917 const char *ptr = block->data();
918 const int count = block->pointCount();
919 const std::size_t recordSize = block->attributes().pointRecordSize();
926 bool alreadyPrintedDebug =
false;
928 QList<QgsPointCloudCategory> categoriesList = symbol->
categoriesList();
929 QVector<int> categoriesValues;
932 categoriesValues.push_back(
c.value() );
936 for (
int i = 0; i < count; ++i )
941 const qint32 ix = *( qint32 * )( ptr + i * recordSize + xOffset );
942 const qint32 iy = *( qint32 * )( ptr + i * recordSize + yOffset );
943 const qint32 iz = *( qint32 * )( ptr + i * recordSize + zOffset );
945 double x = blockOffset.
x() + blockScale.
x() * ix;
946 double y = blockOffset.
y() + blockScale.
y() * iy;
947 double z = ( blockOffset.
z() + blockScale.
z() * iz ) * zValueScale + zValueOffset;
954 if ( !alreadyPrintedDebug )
956 QgsDebugError( QStringLiteral(
"Error transforming point coordinate" ) );
957 alreadyPrintedDebug =
true;
961 const QgsVector3D p = context.map().mapToWorldCoordinates( point );
970 context.
getAttribute( ptr, i * recordSize + attributeOffset, attributeType, iParam );
972 if ( filteredOutValues.contains( (
int ) iParam ) ||
973 ! categoriesValues.contains( (
int ) iParam ) )
975 outNormal.positions.push_back( QVector3D( p.
x(), p.
y(), p.
z() ) );
978 float iParam2 = categoriesValues.indexOf( (
int )iParam ) + 1;
979 outNormal.parameter.push_back( iParam2 );
985 makeEntity( parent, context, outNormal,
false );
988Qt3DQGeometry *QgsClassificationPointCloud3DSymbolHandler::makeGeometry( Qt3DCore::QNode *parent,
const QgsPointCloud3DSymbolHandler::PointData &data,
unsigned int byteStride )
990 return new QgsColorRampPointCloud3DGeometry( parent, data, byteStride );
Represents a indexed point cloud node in octree.
IndexedPointCloudNode parentNode() const
Returns the parent of the node.
float xExtent() const
Returns box width in X axis.
float zExtent() const
Returns box width in Z axis.
bool intersects(const QgsAABB &other) const
Determines whether the box intersects some other axis aligned box.
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.
QString attribute() const
Returns the attribute used to select the color of the point cloud.
Manipulates raster or point cloud pixel values so that they enhanceContrast or clip into a specified ...
@ 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.
Encapsulates the render context for a 3D point cloud rendering operation.
QgsRectangle extent() const
Returns the 3D scene's extent in layer crs.
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.
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 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.
virtual void fillMaterial(Qt3DRender::QMaterial *material)=0SIP_SKIP
Used to fill material object with necessary QParameters (and consequently opengl uniforms)
bool renderAsTriangles() const
Returns whether points are triangulated to render solid surface.
float pointSize() const
Returns the point size of the point cloud.
bool horizontalTriangleFilter() const
Returns whether triangles are filtered by horizontal size for rendering.
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.
Represents a indexed point clouds data in octree.
int span() const
Returns the number of points in one direction in a single node.
virtual QgsPointCloudBlockRequest * asyncNodeData(const IndexedPointCloudNode &n, const QgsPointCloudRequest &request)=0
Returns a handle responsible for loading a node data block.
@ Remote
Remote means it's loaded through a protocol like HTTP.
@ Local
Local means the source is a local file on the machine.
virtual AccessType accessType() const =0
Returns the access type of the data If the access type is Remote, data will be fetched from an HTTP s...
virtual std::unique_ptr< QgsPointCloudBlock > nodeData(const IndexedPointCloudNode &n, const QgsPointCloudRequest &request)=0
Returns node data block.
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.
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.
Class for storage of 3D vectors similar to QVector3D, with the difference that it uses double precisi...
double y() const
Returns Y coordinate.
double z() const
Returns Z coordinate.
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)