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 );
472 if ( pc->
accessType() == QgsPointCloudIndex::AccessType::Local )
476 else if ( pc->
accessType() == QgsPointCloudIndex::AccessType::Remote )
478 bool loopAborted =
false;
490 block = req->
block();
497QgsSingleColorPointCloud3DSymbolHandler::QgsSingleColorPointCloud3DSymbolHandler()
498 : QgsPointCloud3DSymbolHandler()
518 std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
522 const char *ptr = block->
data();
530 bool alreadyPrintedDebug =
false;
532 for (
int i = 0; i < count; ++i )
537 const qint32 ix = *( qint32 * )( ptr + i * recordSize + 0 );
538 const qint32 iy = *( qint32 * )( ptr + i * recordSize + 4 );
539 const qint32 iz = *( qint32 * )( ptr + i * recordSize + 8 );
541 double x = blockOffset.
x() + blockScale.
x() * ix;
542 double y = blockOffset.
y() + blockScale.
y() * iy;
543 double z = ( blockOffset.
z() + blockScale.
z() * iz ) * zValueScale + zValueOffset;
550 if ( !alreadyPrintedDebug )
552 QgsDebugMsg( QStringLiteral(
"Error transforming point coordinate" ) );
553 alreadyPrintedDebug =
true;
558 outNormal.positions.push_back( QVector3D( p.
x(), p.
y(), p.
z() ) );
564 makeEntity( parent, context, outNormal,
false );
567Qt3DQGeometry *QgsSingleColorPointCloud3DSymbolHandler::makeGeometry( Qt3DCore::QNode *parent,
const QgsPointCloud3DSymbolHandler::PointData &data,
unsigned int byteStride )
569 return new QgsSingleColorPointCloud3DGeometry( parent, data, byteStride );
572QgsColorRampPointCloud3DSymbolHandler::QgsColorRampPointCloud3DSymbolHandler()
573 : QgsPointCloud3DSymbolHandler()
587 const int xOffset = 0;
594 QString attributeName;
595 bool attrIsX =
false;
596 bool attrIsY =
false;
597 bool attrIsZ =
false;
599 int attributeOffset = 0;
603 bool alreadyPrintedDebug =
false;
611 if ( symbol->
attribute() == QLatin1String(
"X" ) )
615 else if ( symbol->
attribute() == QLatin1String(
"Y" ) )
619 else if ( symbol->
attribute() == QLatin1String(
"Z" ) )
628 attributeType = attr->
type();
629 attributeName = attr->
name();
636 if ( attributeName.isEmpty() && !attrIsX && !attrIsY && !attrIsZ )
641 std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
645 const char *ptr = block->
data();
652 for (
int i = 0; i < count; ++i )
657 const qint32 ix = *( qint32 * )( ptr + i * recordSize + xOffset );
658 const qint32 iy = *( qint32 * )( ptr + i * recordSize + yOffset );
659 const qint32 iz = *( qint32 * )( ptr + i * recordSize + zOffset );
661 double x = blockOffset.
x() + blockScale.
x() * ix;
662 double y = blockOffset.
y() + blockScale.
y() * iy;
663 double z = ( blockOffset.
z() + blockScale.
z() * iz ) * zValueScale + zValueOffset;
670 if ( !alreadyPrintedDebug )
672 QgsDebugMsg( QStringLiteral(
"Error transforming point coordinate" ) );
673 alreadyPrintedDebug =
true;
677 point = context.map().mapToWorldCoordinates( point );
678 outNormal.positions.push_back( QVector3D( point.x(), point.y(), point.z() ) );
681 outNormal.parameter.push_back( x );
683 outNormal.parameter.push_back( y );
685 outNormal.parameter.push_back( z );
689 context.
getAttribute( ptr, i * recordSize + attributeOffset, attributeType, iParam );
690 outNormal.parameter.push_back( iParam );
697 makeEntity( parent, context, outNormal,
false );
700Qt3DQGeometry *QgsColorRampPointCloud3DSymbolHandler::makeGeometry( Qt3DCore::QNode *parent,
const QgsPointCloud3DSymbolHandler::PointData &data,
unsigned int byteStride )
702 return new QgsColorRampPointCloud3DGeometry( parent, data, byteStride );
705QgsRGBPointCloud3DSymbolHandler::QgsRGBPointCloud3DSymbolHandler()
706 : QgsPointCloud3DSymbolHandler()
746 std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
750 const char *ptr = block->
data();
759 bool alreadyPrintedDebug =
false;
772 for (
int i = 0; i < count; ++i )
777 const qint32 ix = *( qint32 * )( ptr + i * recordSize + 0 );
778 const qint32 iy = *( qint32 * )( ptr + i * recordSize + 4 );
779 const qint32 iz = *( qint32 * )( ptr + i * recordSize + 8 );
780 double x = blockOffset.
x() + blockScale.
x() * ix;
781 double y = blockOffset.
y() + blockScale.
y() * iy;
782 double z = ( blockOffset.
z() + blockScale.
z() * iz ) * zValueScale + zValueOffset;
789 if ( !alreadyPrintedDebug )
791 QgsDebugMsg( QStringLiteral(
"Error transforming point coordinate" ) );
792 alreadyPrintedDebug =
true;
796 const QgsVector3D p = context.map().mapToWorldCoordinates( point );
798 QVector3D color( 0.0f, 0.0f, 0.0f );
800 context.
getAttribute( ptr, i * recordSize + redOffset, redType, ir );
801 context.
getAttribute( ptr, i * recordSize + greenOffset, greenType, ig );
802 context.
getAttribute( ptr, i * recordSize + blueOffset, blueType, ib );
813 if ( useRedContrastEnhancement )
817 if ( useGreenContrastEnhancement )
821 if ( useBlueContrastEnhancement )
826 color.setX( ir / 255.0f );
827 color.setY( ig / 255.0f );
828 color.setZ( ib / 255.0f );
830 outNormal.positions.push_back( QVector3D( p.
x(), p.
y(), p.
z() ) );
831 outNormal.colors.push_back( color );
837 makeEntity( parent, context, outNormal,
false );
840Qt3DQGeometry *QgsRGBPointCloud3DSymbolHandler::makeGeometry( Qt3DCore::QNode *parent,
const QgsPointCloud3DSymbolHandler::PointData &data,
unsigned int byteStride )
842 return new QgsRGBPointCloud3DGeometry( parent, data, byteStride );
845QgsClassificationPointCloud3DSymbolHandler::QgsClassificationPointCloud3DSymbolHandler()
846 : QgsPointCloud3DSymbolHandler()
860 const int xOffset = 0;
867 QString attributeName;
868 bool attrIsX =
false;
869 bool attrIsY =
false;
870 bool attrIsZ =
false;
872 int attributeOffset = 0;
879 if ( symbol->
attribute() == QLatin1String(
"X" ) )
883 else if ( symbol->
attribute() == QLatin1String(
"Y" ) )
887 else if ( symbol->
attribute() == QLatin1String(
"Z" ) )
896 attributeType = attr->
type();
897 attributeName = attr->
name();
904 if ( attributeName.isEmpty() && !attrIsX && !attrIsY && !attrIsZ )
909 std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
913 const char *ptr = block->
data();
922 bool alreadyPrintedDebug =
false;
924 QList<QgsPointCloudCategory> categoriesList = symbol->
categoriesList();
925 QVector<int> categoriesValues;
928 categoriesValues.push_back(
c.value() );
932 for (
int i = 0; i < count; ++i )
937 const qint32 ix = *( qint32 * )( ptr + i * recordSize + xOffset );
938 const qint32 iy = *( qint32 * )( ptr + i * recordSize + yOffset );
939 const qint32 iz = *( qint32 * )( ptr + i * recordSize + zOffset );
941 double x = blockOffset.
x() + blockScale.
x() * ix;
942 double y = blockOffset.
y() + blockScale.
y() * iy;
943 double z = ( blockOffset.
z() + blockScale.
z() * iz ) * zValueScale + zValueOffset;
950 if ( !alreadyPrintedDebug )
952 QgsDebugMsg( QStringLiteral(
"Error transforming point coordinate" ) );
953 alreadyPrintedDebug =
true;
957 const QgsVector3D p = context.map().mapToWorldCoordinates( point );
966 context.
getAttribute( ptr, i * recordSize + attributeOffset, attributeType, iParam );
968 if ( filteredOutValues.contains( (
int ) iParam ) ||
969 ! categoriesValues.contains( (
int ) iParam ) )
971 outNormal.positions.push_back( QVector3D( p.
x(), p.
y(), p.
z() ) );
974 float iParam2 = categoriesValues.indexOf( (
int )iParam ) + 1;
975 outNormal.parameter.push_back( iParam2 );
981 makeEntity( parent, context, outNormal,
false );
984Qt3DQGeometry *QgsClassificationPointCloud3DSymbolHandler::makeGeometry( Qt3DCore::QNode *parent,
const QgsPointCloud3DSymbolHandler::PointData &data,
unsigned int byteStride )
986 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.
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.
QgsPointCloudBlock * block()
Returns the requested block.
void finished()
Emitted when the request processing has finished.
Base class for storing raw data from point cloud nodes.
QgsVector3D scale() const
Returns the custom scale of the block.
const char * data() const
Returns raw pointer to data.
QgsPointCloudAttributeCollection attributes() const
Returns the attributes that are stored in the data block, along with their size.
int pointCount() const
Returns number of points that are stored in the block.
QgsVector3D offset() const
Returns the custom offset of the 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.
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 QgsPointCloudBlock * nodeData(const IndexedPointCloudNode &n, const QgsPointCloudRequest &request)=0
Returns node data block.
Point cloud data request.
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.
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)