26
26
QgsLayoutItem3DMap::QgsLayoutItem3DMap ( QgsLayout *layout )
27
27
: QgsLayoutItem( layout )
28
28
{
29
+ connect ( this , &QgsLayoutItem::sizePositionChanged, this , &QgsLayoutItem3DMap::onSizePositionChanged );
29
30
}
30
31
31
32
QgsLayoutItem3DMap::~QgsLayoutItem3DMap () = default ;
@@ -43,30 +44,80 @@ int QgsLayoutItem3DMap::type() const
43
44
44
45
void QgsLayoutItem3DMap::draw ( QgsLayoutItemRenderContext &context )
45
46
{
47
+ QgsRenderContext &ctx = context.renderContext ();
48
+ QPainter *painter = ctx.painter ();
49
+
50
+ int w = static_cast <int >( std::ceil ( rect ().width () * ctx.scaleFactor () ) );
51
+ int h = static_cast <int >( std::ceil ( rect ().height () * ctx.scaleFactor () ) );
52
+ QRect r ( 0 , 0 , w, h );
53
+
54
+ painter->save ();
55
+
46
56
if ( !mSettings )
57
+ {
58
+ painter->drawText ( r, Qt::AlignCenter, tr ( " Scene not set" ) );
59
+ painter->restore ();
60
+ return ;
61
+ }
62
+
63
+ if ( !mCapturedImage .isNull () )
64
+ {
65
+ painter->drawImage ( r, mCapturedImage );
66
+ painter->restore ();
47
67
return ;
68
+ }
69
+
70
+ // we do not have a cached image of the rendered scene - let's request one from the engine
71
+
72
+ painter->drawText ( r, Qt::AlignCenter, tr ( " Loading" ) );
73
+ painter->restore ();
48
74
49
- QgsOffscreen3DEngine engine;
50
75
QSizeF sizePixels = mLayout ->renderContext ().measurementConverter ().convert ( sizeWithUnits (), QgsUnitTypes::LayoutPixels ).toQSizeF ();
51
- engine. setSize ( QSize ( static_cast <int >( std::ceil ( sizePixels.width () ) ),
52
- static_cast <int >( std::ceil ( sizePixels.height () ) ) ) );
76
+ QSize sizePixelsInt = QSize ( static_cast <int >( std::ceil ( sizePixels.width () ) ),
77
+ static_cast <int >( std::ceil ( sizePixels.height () ) ) );
53
78
54
- Qgs3DMapScene *scene = new Qgs3DMapScene ( *mSettings , &engine );
55
- engine.setRootEntity ( scene );
79
+ if ( !mEngine )
80
+ {
81
+ mEngine .reset ( new QgsOffscreen3DEngine );
82
+ connect ( mEngine .get (), &QgsAbstract3DEngine::imageCaptured, this , &QgsLayoutItem3DMap::onImageCaptured );
56
83
57
- scene-> cameraController ()-> setCameraPose ( mCameraPose );
84
+ mEngine -> setSize ( sizePixelsInt );
58
85
59
- // XXX this should not be needed, but without it the scene often
60
- // is not completely ready (e.g. a missing terrain tile).
61
- // leaving it here until a more robust solution is found...
62
- Qgs3DUtils::captureSceneImage ( engine, scene );
86
+ mScene = new Qgs3DMapScene ( *mSettings , mEngine .get () );
87
+ connect ( mScene , &Qgs3DMapScene::sceneStateChanged, this , &QgsLayoutItem3DMap::onSceneStateChanged );
63
88
64
- QImage img = Qgs3DUtils::captureSceneImage ( engine, scene );
89
+ mEngine ->setRootEntity ( mScene );
90
+ }
65
91
66
- QgsRenderContext &ctx = context.renderContext ();
67
- ctx.painter ()->drawImage ( 0 , 0 , img );
92
+ if ( mEngine ->size () != sizePixelsInt )
93
+ mEngine ->setSize ( sizePixelsInt );
94
+
95
+ mScene ->cameraController ()->setCameraPose ( mCameraPose );
96
+
97
+ onSceneStateChanged ();
98
+ }
99
+
100
+ void QgsLayoutItem3DMap::onImageCaptured ( const QImage &img )
101
+ {
102
+ mCapturedImage = img;
103
+ update ();
104
+ }
105
+
106
+ void QgsLayoutItem3DMap::onSceneStateChanged ()
107
+ {
108
+ if ( mCapturedImage .isNull () && mScene ->sceneState () == Qgs3DMapScene::Ready )
109
+ {
110
+ mEngine ->requestCaptureImage ();
111
+ }
112
+ }
113
+
114
+ void QgsLayoutItem3DMap::onSizePositionChanged ()
115
+ {
116
+ mCapturedImage = QImage ();
117
+ update ();
68
118
}
69
119
120
+
70
121
bool QgsLayoutItem3DMap::writePropertiesToElement ( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const
71
122
{
72
123
if ( mSettings )
@@ -83,6 +134,7 @@ bool QgsLayoutItem3DMap::writePropertiesToElement( QDomElement &element, QDomDoc
83
134
84
135
bool QgsLayoutItem3DMap::readPropertiesFromElement ( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context )
85
136
{
137
+ Q_UNUSED ( document );
86
138
QDomElement elemSettings = element.firstChildElement ( " qgis3d" );
87
139
if ( !elemSettings.isNull () )
88
140
{
@@ -102,4 +154,20 @@ bool QgsLayoutItem3DMap::readPropertiesFromElement( const QDomElement &element,
102
154
void QgsLayoutItem3DMap::setMapSettings ( Qgs3DMapSettings *settings )
103
155
{
104
156
mSettings .reset ( settings );
157
+
158
+ mEngine .reset ();
159
+ mScene = nullptr ;
160
+
161
+ mCapturedImage = QImage ();
162
+ update ();
163
+ }
164
+
165
+ void QgsLayoutItem3DMap::setCameraPose ( const QgsCameraPose &pose )
166
+ {
167
+ if ( mCameraPose == pose )
168
+ return ;
169
+
170
+ mCameraPose = pose;
171
+ mCapturedImage = QImage ();
172
+ update ();
105
173
}
0 commit comments