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 );
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.
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.
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.
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.
@ 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 QgsPointCloudBlockRequest * asyncNodeData(const QgsPointCloudNodeId &n, const QgsPointCloudRequest &request)=0
Returns a handle responsible for loading a node data block.
virtual QgsPointCloudNode getNode(const QgsPointCloudNodeId &id) const
Returns object for a given node.
virtual std::unique_ptr< QgsPointCloudBlock > nodeData(const QgsPointCloudNodeId &n, const QgsPointCloudRequest &request)=0
Returns node data block.
Represents a indexed point cloud node's position in octree.
QgsPointCloudNodeId parentNode() const
Returns the parent of the node.
Keeps metadata for 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.
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.
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)