1 /***************************************************************************
2   qgsfeature3dhandler_p.h
3   --------------------------------------
4   Date                 : January 2019
5   Copyright            : (C) 2019 by Martin Dobias
6   Email                : wonder 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 QGSFEATURE3DHANDLER_P_H
17 #define QGSFEATURE3DHANDLER_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 <Qt3DCore/QEntity>
31 
32 class QgsFeature;
33 
34 
35 #include "qgsexpressioncontext.h"
36 
37 class Qgs3DMapSettings;
38 
39 #define SIP_NO_FILE
40 
41 
42 /**
43  * \ingroup 3d
44  * \brief Rendering context for preparation of 3D entities.
45  *
46  * \note Not available in Python bindings
47  */
48 class Qgs3DRenderContext
49 {
50   public:
Qgs3DRenderContext(const Qgs3DMapSettings & map)51     Qgs3DRenderContext( const Qgs3DMapSettings &map ) : mMap( map ) {}
52 
map()53     const Qgs3DMapSettings &map() const { return mMap; }
54 
55     /**
56      * Sets the expression context. This context is used for all expression evaluation
57      * associated with this render context.
58      * \see expressionContext()
59      */
setExpressionContext(const QgsExpressionContext & context)60     void setExpressionContext( const QgsExpressionContext &context ) { mExpressionContext = context; }
61 
62     /**
63      * Gets the expression context. This context should be used for all expression evaluation
64      * associated with this render context.
65      * \see setExpressionContext()
66      */
expressionContext()67     QgsExpressionContext &expressionContext() { return mExpressionContext; }
68 
69     /**
70      * Gets the expression context (const version). This context should be used for all expression evaluation
71      * associated with this render context.
72      * \see setExpressionContext()
73      * \note not available in Python bindings
74      */
expressionContext()75     const QgsExpressionContext &expressionContext() const { return mExpressionContext; } SIP_SKIP
76 
77   private:
78     const Qgs3DMapSettings &mMap;
79     //! Expression context
80     QgsExpressionContext mExpressionContext;
81 
82 };
83 
84 
85 /**
86  * \ingroup 3d
87  * \brief Interface to be implemented by 3D symbol implementations in order to generate 3D entities.
88  */
89 class QgsFeature3DHandler
90 {
91   public:
92     virtual ~QgsFeature3DHandler() = default;
93 
94     /**
95      * Called before feature iteration starts to initialize, get required attributes.
96      * \returns TRUE on success (on FALSE the handler failed to initialize and processFeature() / finalize() should not be called
97      */
98     virtual bool prepare( const Qgs3DRenderContext &context, QSet<QString> &attributeNames ) = 0;
99 
100     /**
101      * Called for every feature to extract information out of it into some
102      * temporary variables in the derived handler class.
103      */
104     virtual void processFeature( const QgsFeature &feature, const Qgs3DRenderContext &context ) = 0;
105 
106     /**
107      * When feature iteration has finished, finalize() is called to turn the extracted data
108      * to a 3D entity object(s) attached to the given parent.
109      */
110     virtual void finalize( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context ) = 0;
111 
112     /**
113      * Returns minimal Z value of the data (in world coordinates).
114      * \note this method should not be called before call to finalize() - it may not be initialized
115      */
zMinimum()116     float zMinimum() const { return mZMin; }
117 
118     /**
119      * Returns maximal Z value of the data (in world coordinates).
120      * \note this method should not be called before call to finalize() - it may not be initialized
121      */
zMaximum()122     float zMaximum() const { return mZMax; }
123 
124   protected:
125     //! updates zMinimum, zMaximum from the vector of positions in 3D world coordinates
126     void updateZRangeFromPositions( const QVector<QVector3D> &positions );
127 
128   protected:
129     float mZMin = std::numeric_limits<float>::max();
130     float mZMax = std::numeric_limits<float>::lowest();
131 };
132 
133 
134 class Qgs3DMapSettings;
135 class QgsVectorLayer;
136 
137 namespace Qgs3DSymbolImpl
138 {
139   //! generic method to iterate over a layer, handle features with handler and create an entity out of it
140   Qt3DCore::QEntity *entityFromHandler( QgsFeature3DHandler *handler, const Qgs3DMapSettings &map, QgsVectorLayer *layer );
141 }
142 
143 
144 /// @endcond
145 
146 #endif // QGSFEATURE3DHANDLER_P_H
147