1 /***************************************************************************
2   qgsrubberband3d.cpp
3   --------------------------------------
4   Date                 : June 2021
5   Copyright            : (C) 2021 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 #include "qgsrubberband3d.h"
17 
18 #include "qgscameracontroller.h"
19 #include "qgslinevertexdata_p.h"
20 #include "qgsabstractmaterialsettings.h"
21 #include "qgslinematerial_p.h"
22 #include "qgsphongmaterialsettings.h"
23 
24 #include "qgslinestring.h"
25 
26 #include <Qt3DCore/QEntity>
27 #include <Qt3DRender/QAttribute>
28 #include <Qt3DRender/QBuffer>
29 #include <Qt3DRender/QGeometry>
30 #include <Qt3DRender/QGeometryRenderer>
31 #include <Qt3DRender/QMaterial>
32 
33 
34 /// @cond PRIVATE
35 
36 
QgsRubberBand3D(Qgs3DMapSettings & map,QgsCameraController * cameraController,Qt3DCore::QEntity * parentEntity)37 QgsRubberBand3D::QgsRubberBand3D( Qgs3DMapSettings &map, QgsCameraController *cameraController, Qt3DCore::QEntity *parentEntity )
38 {
39   mMapSettings = &map;
40 
41   mEntity = new Qt3DCore::QEntity( parentEntity );
42 
43   QgsLineVertexData dummyLineData;
44   mGeometry = dummyLineData.createGeometry( mEntity );
45 
46   Q_ASSERT( mGeometry->attributes().count() == 2 );
47   mPositionAttribute = mGeometry->attributes()[0];
48   mIndexAttribute = mGeometry->attributes()[1];
49 
50   mGeomRenderer = new Qt3DRender::QGeometryRenderer;
51   mGeomRenderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::LineStripAdjacency );
52   mGeomRenderer->setGeometry( mGeometry );
53   mGeomRenderer->setPrimitiveRestartEnabled( true );
54   mGeomRenderer->setRestartIndexValue( 0 );
55 
56   mEntity->addComponent( mGeomRenderer );
57 
58   mLineMaterial = new QgsLineMaterial;
59   mLineMaterial->setLineWidth( 3 );
60   mLineMaterial->setLineColor( Qt::red );
61 
62   QObject::connect( cameraController, &QgsCameraController::viewportChanged, mLineMaterial, [this, cameraController]
63   {
64     mLineMaterial->setViewportSize( cameraController->viewport().size() );
65   } );
66   mLineMaterial->setViewportSize( cameraController->viewport().size() );
67 
68   mEntity->addComponent( mLineMaterial );
69 }
70 
~QgsRubberBand3D()71 QgsRubberBand3D::~QgsRubberBand3D()
72 {
73   delete mEntity;
74 }
75 
width() const76 float QgsRubberBand3D::width() const
77 {
78   return mLineMaterial->lineWidth();
79 }
80 
setWidth(float width)81 void QgsRubberBand3D::setWidth( float width )
82 {
83   mLineMaterial->setLineWidth( width );
84 }
85 
color() const86 QColor QgsRubberBand3D::color() const
87 {
88   return mLineMaterial->lineColor();
89 }
90 
setColor(QColor color)91 void QgsRubberBand3D::setColor( QColor color )
92 {
93   mLineMaterial->setLineColor( color );
94 }
95 
reset()96 void QgsRubberBand3D::reset()
97 {
98   mLineString.clear();
99   updateGeometry();
100 }
101 
addPoint(const QgsPoint & pt)102 void QgsRubberBand3D::addPoint( const QgsPoint &pt )
103 {
104   mLineString.addVertex( pt );
105   updateGeometry();
106 }
107 
removeLastPoint()108 void QgsRubberBand3D::removeLastPoint()
109 {
110   const int lastVertexIndex = mLineString.numPoints() - 1;
111   mLineString.deleteVertex( QgsVertexId( 0, 0, lastVertexIndex ) );
112   updateGeometry();
113 }
114 
updateGeometry()115 void QgsRubberBand3D::updateGeometry()
116 {
117   QgsLineVertexData lineData;
118   lineData.withAdjacency = true;
119   lineData.init( Qgs3DTypes::AltClampAbsolute, Qgs3DTypes::AltBindVertex, 0, mMapSettings );
120   lineData.addLineString( mLineString );
121 
122   mPositionAttribute->buffer()->setData( lineData.createVertexBuffer() );
123   mIndexAttribute->buffer()->setData( lineData.createIndexBuffer() );
124   mGeomRenderer->setVertexCount( lineData.indexes.count() );
125 }
126 
127 /// @endcond
128