QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsmesh3dsymbol_p.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmesh3dsymbol_p.cpp
3  ---------------------
4  Date : January 2019
5  Copyright : (C) 2019 by Peter Petrik
6  Email : zilolv 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 "qgsmesh3dsymbol_p.h"
17 
18 #include "qgsmesh3dsymbol.h"
20 #include "qgs3dmapsettings.h"
21 #include "qgs3dutils.h"
22 
23 #include <Qt3DCore/QTransform>
24 #include <Qt3DRender/QEffect>
25 #include <Qt3DRender/QTechnique>
26 #include <Qt3DRender/QCullFace>
27 
28 #include "qgsmultipolygon.h"
29 #include "qgsmeshlayer.h"
30 #include "qgstriangularmesh.h"
32 
33 static QgsExpressionContext _expressionContext3D()
34 {
38  return ctx;
39 }
40 
42 
43 QgsMesh3DSymbolEntity::QgsMesh3DSymbolEntity( const Qgs3DMapSettings &map,
44  QgsMeshLayer *layer,
45  const QgsMesh3DSymbol &symbol,
46  Qt3DCore::QNode *parent )
47  : Qt3DCore::QEntity( parent )
48 {
49  // build the default material
50  Qt3DExtras::QPhongMaterial *mat = material( symbol );
51 
52  // build a transform function
53  Qt3DCore::QTransform *tform = new Qt3DCore::QTransform;
54  tform->setTranslation( QVector3D( 0, 0, 0 ) );
55 
56  // build the entity
57  QgsMesh3DSymbolEntityNode *entity = new QgsMesh3DSymbolEntityNode( map, layer, symbol );
58  entity->findChild<Qt3DRender::QGeometryRenderer *>()->setObjectName( QStringLiteral( "main" ) ); // temporary measure to distinguish between "selected" and "main"
59  entity->addComponent( mat );
60  entity->addComponent( tform );
61  entity->setParent( this );
62 }
63 
64 Qt3DExtras::QPhongMaterial *QgsMesh3DSymbolEntity::material( const QgsMesh3DSymbol &symbol ) const
65 {
66  Qt3DExtras::QPhongMaterial *material = new Qt3DExtras::QPhongMaterial;
67 
68  // front/back side culling
69  auto techniques = material->effect()->techniques();
70  for ( auto tit = techniques.constBegin(); tit != techniques.constEnd(); ++tit )
71  {
72  auto renderPasses = ( *tit )->renderPasses();
73  for ( auto rpit = renderPasses.begin(); rpit != renderPasses.end(); ++rpit )
74  {
75  Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace;
76  cullFace->setMode( Qt3DRender::QCullFace::Back );
77  ( *rpit )->addRenderState( cullFace );
78  }
79  }
80 
81  material->setAmbient( symbol.material().ambient() );
82  material->setDiffuse( symbol.material().diffuse() );
83  material->setSpecular( symbol.material().specular() );
84  material->setShininess( symbol.material().shininess() );
85  return material;
86 }
87 
88 QgsMesh3DSymbolEntityNode::QgsMesh3DSymbolEntityNode( const Qgs3DMapSettings &map,
89  QgsMeshLayer *layer,
90  const QgsMesh3DSymbol &symbol,
91  Qt3DCore::QNode *parent ) : Qt3DCore::QEntity( parent )
92 {
93  addComponent( renderer( map, symbol, layer ) );
94 }
95 
96 Qt3DRender::QGeometryRenderer *QgsMesh3DSymbolEntityNode::renderer( const Qgs3DMapSettings &map,
97  const QgsMesh3DSymbol &symbol,
98  const QgsMeshLayer *layer )
99 {
100  QgsPointXY origin( map.origin().x(), map.origin().y() );
101  QList<QgsPolygon *> polygons;
102  QList<QgsFeatureId> fids;
103 
104  QgsExpressionContext ctx( _expressionContext3D() );
105  const QgsPropertyCollection &ddp = symbol.dataDefinedProperties();
106  bool hasDDHeight = ddp.isActive( QgsAbstract3DSymbol::PropertyHeight );
107  float height = symbol.height();
108  if ( hasDDHeight )
109  {
110  height = static_cast<float>( ddp.valueAsDouble( QgsAbstract3DSymbol::PropertyHeight,
111  ctx,
112  static_cast<double>( height )
113  )
114  );
115  }
116 
117  const QgsTriangularMesh *mesh = layer->triangularMesh();
118  if ( mesh )
119  {
120  const QVector<QgsMeshFace> &triangles = mesh->triangles();
121  const QVector<QgsMeshVertex> &vertices = mesh->vertices();
122  for ( int i = 0; i < triangles.size(); ++i )
123  {
124  const QgsMeshFace &triangle = triangles.at( i );
125  Q_ASSERT( triangle.size() == 3 );
126  std::unique_ptr< QgsPolygon > polygon = QgsMeshUtils::toPolygon( triangle, vertices );
127  Qgs3DUtils::clampAltitudes( polygon.get(),
128  symbol.altitudeClamping(),
129  Qgs3DTypes::AltitudeBinding::AltBindVertex,
130  height,
131  map );
132  polygons.append( polygon.release() );
133  fids.append( i );
134  }
135  }
136 
137  // Polygons from mesh are already triangles, but
138  // call QgsTessellatedPolygonGeometry to
139  // use symbol settings for back faces, normals, etc
140  mGeometry = new QgsTessellatedPolygonGeometry;
141  mGeometry->setInvertNormals( false );
142  mGeometry->setAddBackFaces( symbol.addBackFaces() );
143  QList<float> extrusionHeightPerPolygon;
144  mGeometry->setPolygons( polygons, fids, origin, 0.0, extrusionHeightPerPolygon );
145 
146  Qt3DRender::QGeometryRenderer *renderer = new Qt3DRender::QGeometryRenderer;
147  renderer->setGeometry( mGeometry );
148 
149  return renderer;
150 }
QgsPhongMaterialSettings::ambient
QColor ambient() const
Returns ambient color component.
Definition: qgsphongmaterialsettings.h:46
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:369
qgsexpressioncontextutils.h
QgsPhongMaterialSettings::diffuse
QColor diffuse() const
Returns diffuse color component.
Definition: qgsphongmaterialsettings.h:48
QgsAbstractPropertyCollection::valueAsDouble
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
Definition: qgspropertycollection.cpp:66
qgstessellatedpolygongeometry.h
QgsPhongMaterialSettings::specular
QColor specular() const
Returns specular color component.
Definition: qgsphongmaterialsettings.h:50
QgsTriangularMesh::vertices
const QVector< QgsMeshVertex > & vertices() const
Returns vertices in map coordinate system.
Definition: qgstriangularmesh.cpp:287
QgsExpressionContextUtils::globalScope
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Definition: qgsexpressioncontextutils.cpp:33
QgsVector3D::y
double y() const
Returns Y coordinate.
Definition: qgsvector3d.h:64
qgsmesh3dsymbol.h
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:458
QgsTriangularMesh::triangles
const QVector< QgsMeshFace > & triangles() const
Returns triangles.
Definition: qgstriangularmesh.cpp:292
QgsMesh3DSymbol
Definition: qgsmesh3dsymbol.h:42
QgsMesh3DSymbol::height
float height() const
Returns height (altitude) of the symbol (in map units)
Definition: qgsmesh3dsymbol.h:103
QgsAbstract3DSymbol::PropertyHeight
@ PropertyHeight
Height (altitude)
Definition: qgsabstract3dsymbol.h:59
Qgs3DUtils::clampAltitudes
static void clampAltitudes(QgsLineString *lineString, Qgs3DTypes::AltitudeClamping altClamp, Qgs3DTypes::AltitudeBinding altBind, const QgsPoint &centroid, float height, const Qgs3DMapSettings &map)
Clamps altitude of vertices of a linestring according to the settings.
Definition: qgs3dutils.cpp:267
QgsTessellatedPolygonGeometry::setInvertNormals
void setInvertNormals(bool invert)
Sets whether the normals of triangles will be inverted (useful for fixing clockwise / counter-clockwi...
Definition: qgstessellatedpolygongeometry.h:52
QgsMeshLayer::triangularMesh
QgsTriangularMesh * triangularMesh(double minimumTriangleSize=0) const
Returns triangular mesh (nullptr before rendering or calling to updateMesh).
Definition: qgsmeshlayer.cpp:224
QgsMesh3DSymbol::addBackFaces
bool addBackFaces() const
Returns whether also triangles facing the other side will be created.
Definition: qgsmesh3dsymbol.h:115
QgsMesh3DSymbol::altitudeClamping
Qgs3DTypes::AltitudeClamping altitudeClamping() const
Returns method that determines altitude (whether to clamp to feature to terrain)
Definition: qgsmesh3dsymbol.h:98
QgsMesh3DSymbol::material
QgsPhongMaterialSettings material() const
Returns material used for shading of the symbol.
Definition: qgsmesh3dsymbol.h:108
qgstriangularmesh.h
QgsExpressionContextUtils::projectScope
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
Definition: qgsexpressioncontextutils.cpp:221
qgsmultipolygon.h
qgs3dutils.h
QgsMeshUtils::toPolygon
CORE_EXPORT std::unique_ptr< QgsPolygon > toPolygon(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns face as polygon geometry, caller is responsible for delete.
Definition: qgstriangularmesh.cpp:509
QgsMeshLayer
Definition: qgsmeshlayer.h:94
Qt3DCore
Definition: qgsabstract3drenderer.h:30
Qgs3DMapSettings
Definition: qgs3dmapsettings.h:51
qgsmesh3dsymbol_p.h
Qgs3DMapSettings::origin
QgsVector3D origin() const
Returns coordinates in map CRS at which 3D scene has origin (0,0,0)
Definition: qgs3dmapsettings.h:84
QgsMeshFace
QVector< int > QgsMeshFace
List of vertex indexes.
Definition: qgsmeshdataprovider.h:41
qgsmeshlayer.h
QgsPointXY
Definition: qgspointxy.h:43
QgsPropertyCollection
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
Definition: qgspropertycollection.h:318
qgs3dmapsettings.h
QgsAbstract3DSymbol::dataDefinedProperties
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
Definition: qgsabstract3dsymbol.h:67
QgsPhongMaterialSettings::shininess
float shininess() const
Returns shininess of the surface.
Definition: qgsphongmaterialsettings.h:52
QgsTriangularMesh
Definition: qgstriangularmesh.h:49
QgsPropertyCollection::isActive
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
Definition: qgspropertycollection.cpp:258
QgsVector3D::x
double x() const
Returns X coordinate.
Definition: qgsvector3d.h:62
QgsTessellatedPolygonGeometry
Definition: qgstessellatedpolygongeometry.h:42