1 /***************************************************************************
2   qgspointcloudlayerchunkloader_p.h
3   --------------------------------------
4   Date                 : October 2020
5   Copyright            : (C) 2020 by Peter Petrik
6   Email                : zilolv dot sk at gmail dot com
7  ***************************************************************************
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  ***************************************************************************/
15 
16 #ifndef QGSPOINTCLOUDLAYERCHUNKLOADER_P_H
17 #define QGSPOINTCLOUDLAYERCHUNKLOADER_P_H
18 
19 ///@cond PRIVATE
20 
21 //
22 //  W A R N I N G
23 //  -------------
24 //
25 // This file is not part of the QGIS API.  It exists purely as an
26 // implementation detail.  This header file may change from version to
27 // version without notice, or even be removed.
28 //
29 
30 #include "qgschunkloader_p.h"
31 #include "qgsfeature3dhandler_p.h"
32 #include "qgschunkedentity_p.h"
33 #include "qgspointcloud3dsymbol.h"
34 #include "qgspointcloud3dsymbol_p.h"
35 #include "qgspointcloudlayer3drenderer.h"
36 
37 #include <memory>
38 
39 #include <QFutureWatcher>
40 #include <Qt3DRender/QGeometry>
41 #include <Qt3DRender/QBuffer>
42 #include <Qt3DRender/QMaterial>
43 #include <QVector3D>
44 
45 #define SIP_NO_FILE
46 
47 /**
48  * \ingroup 3d
49  * \brief This loader factory is responsible for creation of loaders for individual tiles
50  * of QgsQgsPointCloudLayerChunkedEntity whenever a new tile is requested by the entity.
51  *
52  * \since QGIS 3.18
53  */
54 class QgsPointCloudLayerChunkLoaderFactory : public QgsChunkLoaderFactory
55 {
56   public:
57 
58     /**
59      * Constructs the factory
60      * The factory takes ownership over the passed \a symbol
61      */
62     QgsPointCloudLayerChunkLoaderFactory( const Qgs3DMapSettings &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloudIndex *pc, QgsPointCloud3DSymbol *symbol,
63                                           double zValueScale, double zValueOffset, int pointBudget );
64 
65     //! Creates loader for the given chunk node. Ownership of the returned is passed to the caller.
66     virtual QgsChunkLoader *createChunkLoader( QgsChunkNode *node ) const override;
67     virtual QgsChunkNode *createRootNode() const override;
68     virtual QVector<QgsChunkNode *> createChildren( QgsChunkNode *node ) const override;
69     virtual int primitivesCount( QgsChunkNode *node ) const override;
70     const Qgs3DMapSettings &mMap;
71     QgsCoordinateTransform mCoordinateTransform;
72     QgsPointCloudIndex *mPointCloudIndex;
73     std::unique_ptr< QgsPointCloud3DSymbol > mSymbol;
74     double mZValueScale = 1.0;
75     double mZValueOffset = 0;
76     int mPointBudget = 1000000;
77 };
78 
79 
80 /**
81  * \ingroup 3d
82  * \brief This loader class is responsible for async loading of data for a single tile
83  * of QgsPointCloudLayerChunkedEntity and creation of final 3D entity from the data
84  * previously prepared in a worker thread.
85  *
86  * \since QGIS 3.18
87  */
88 class QgsPointCloudLayerChunkLoader : public QgsChunkLoader
89 {
90   public:
91 
92     /**
93      * Constructs the loader
94      * QgsPointCloudLayerChunkLoader takes ownership over symbol
95      */
96     QgsPointCloudLayerChunkLoader( const QgsPointCloudLayerChunkLoaderFactory *factory, QgsChunkNode *node, std::unique_ptr< QgsPointCloud3DSymbol > symbol,
97                                    const QgsCoordinateTransform &coordinateTransform, double zValueScale, double zValueOffset );
98     ~QgsPointCloudLayerChunkLoader() override;
99 
100     virtual void cancel() override;
101     virtual Qt3DCore::QEntity *createEntity( Qt3DCore::QEntity *parent ) override;
102 
103   private:
104     const QgsPointCloudLayerChunkLoaderFactory *mFactory;
105     std::unique_ptr<QgsPointCloud3DSymbolHandler> mHandler;
106     QgsPointCloud3DRenderContext mContext;
107     QFutureWatcher<void> *mFutureWatcher = nullptr;
108 };
109 
110 
111 /**
112  * \ingroup 3d
113  * \brief 3D entity used for rendering of point cloud layers with a single 3D symbol for all points.
114  *
115  * It is implemented using tiling approach with QgsChunkedEntity. Internally it uses
116  * QgsPointCloudLayerChunkLoaderFactory and QgsPointCloudLayerChunkLoader to do the actual work
117  * of loading and creating 3D sub-entities for each tile.
118  *
119  * \since QGIS 3.18
120  */
121 class QgsPointCloudLayerChunkedEntity : public QgsChunkedEntity
122 {
123     Q_OBJECT
124   public:
125     explicit QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DMapSettings &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maxScreenError, bool showBoundingBoxes,
126         double zValueScale, double zValueOffset, int pointBudget );
127 
128     ~QgsPointCloudLayerChunkedEntity();
129 };
130 
131 /// @endcond
132 
133 #endif // QGSPOINTCLOUDLAYERCHUNKLOADER_P_H
134