Skip to content
Permalink
Browse files

Use QgsFeature3DHandler in 3D point symbol implementation

This is a small refactoring of 3D point symbol code, with three goals:

- use the new handler class just like line and polygon symbols already use

- just one feature loop instead of two and avoiding possibly slow query
  that requests all features by their IDs

- make it possible to use point symbols with rule-based renderer
  • Loading branch information
wonder-sk committed Jan 21, 2019
1 parent 1b11ba4 commit b6f71767fa7115f7a5bc247427ef69bf4829bedf
@@ -31,6 +31,8 @@
#include "qgspoint3dsymbol.h"
#include "qgspolygon3dsymbol.h"

#include <Qt3DExtras/QPhongMaterial>


QImage Qgs3DUtils::captureSceneImage( QgsAbstract3DEngine &engine, Qgs3DMapScene *scene )
{
@@ -247,46 +249,35 @@ QMatrix4x4 Qgs3DUtils::stringToMatrix4x4( const QString &str )
return m;
}

QList<QVector3D> Qgs3DUtils::positions( const Qgs3DMapSettings &map, QgsVectorLayer *layer, const QgsFeatureRequest &request, Qgs3DTypes::AltitudeClamping altClamp )
void Qgs3DUtils::extractPointPositions( QgsFeature &f, const Qgs3DMapSettings &map, Qgs3DTypes::AltitudeClamping altClamp, QVector<QVector3D> &positions )
{
QList<QVector3D> positions;
QgsFeature f;
QgsFeatureIterator fi = layer->getFeatures( request );
while ( fi.nextFeature( f ) )
const QgsAbstractGeometry *g = f.geometry().constGet();
for ( auto it = g->vertices_begin(); it != g->vertices_end(); ++it )
{
if ( f.geometry().isNull() )
continue;

const QgsAbstractGeometry *g = f.geometry().constGet();
for ( auto it = g->vertices_begin(); it != g->vertices_end(); ++it )
QgsPoint pt = *it;
float geomZ = 0;
if ( pt.is3D() )
{
QgsPoint pt = *it;
float geomZ = 0;
if ( pt.is3D() )
{
geomZ = pt.z();
}
float terrainZ = map.terrainGenerator()->heightAt( pt.x(), pt.y(), map ) * map.terrainVerticalScale();
float h;
switch ( altClamp )
{
case Qgs3DTypes::AltClampAbsolute:
default:
h = geomZ;
break;
case Qgs3DTypes::AltClampTerrain:
h = terrainZ;
break;
case Qgs3DTypes::AltClampRelative:
h = terrainZ + geomZ;
break;
}
positions.append( QVector3D( pt.x() - map.origin().x(), h, -( pt.y() - map.origin().y() ) ) );
//qDebug() << positions.last();
geomZ = pt.z();
}
float terrainZ = map.terrainGenerator()->heightAt( pt.x(), pt.y(), map ) * map.terrainVerticalScale();
float h;
switch ( altClamp )
{
case Qgs3DTypes::AltClampAbsolute:
default:
h = geomZ;
break;
case Qgs3DTypes::AltClampTerrain:
h = terrainZ;
break;
case Qgs3DTypes::AltClampRelative:
h = terrainZ + geomZ;
break;
}
positions.append( QVector3D( pt.x() - map.origin().x(), h, -( pt.y() - map.origin().y() ) ) );
//qDebug() << positions.last();
}

return positions;
}

/**
@@ -401,3 +392,13 @@ QgsExpressionContext Qgs3DUtils::globalProjectLayerExpressionContext( QgsVectorL
<< QgsExpressionContextUtils::layerScope( layer );
return exprContext;
}

Qt3DExtras::QPhongMaterial *Qgs3DUtils::phongMaterial( const QgsPhongMaterialSettings &settings )
{
Qt3DExtras::QPhongMaterial *phong = new Qt3DExtras::QPhongMaterial;
phong->setAmbient( settings.ambient() );
phong->setDiffuse( settings.diffuse() );
phong->setSpecular( settings.specular() );
phong->setShininess( settings.shininess() );
return phong;
}
@@ -25,6 +25,11 @@ class QgsAbstract3DEngine;
class QgsAbstract3DSymbol;
class Qgs3DMapScene;

namespace Qt3DExtras
{
class QPhongMaterial;
}

#include "qgs3dmapsettings.h"
#include "qgs3dtypes.h"
#include "qgsaabb.h"
@@ -82,10 +87,8 @@ class _3D_EXPORT Qgs3DUtils
//! Convert a string to a 4x4 transform matrix
static QMatrix4x4 stringToMatrix4x4( const QString &str );

/**
* Calculates (x,y,z) positions of a (multi)point in the Point vector layers
*/
static QList<QVector3D> positions( const Qgs3DMapSettings &map, QgsVectorLayer *layer, const QgsFeatureRequest &req, Qgs3DTypes::AltitudeClamping altClamp );
//! Calculates (x,y,z) positions of (multi)point from the given feature
static void extractPointPositions( QgsFeature &f, const Qgs3DMapSettings &map, Qgs3DTypes::AltitudeClamping altClamp, QVector<QVector3D> &positions );

/**
Returns true if bbox is completely outside the current viewing volume.
@@ -107,6 +110,9 @@ class _3D_EXPORT Qgs3DUtils

//! Returns expression context for use in preparation of 3D data of a layer
static QgsExpressionContext globalProjectLayerExpressionContext( QgsVectorLayer *layer );

//! Returns phong material object based on the material settings
static Qt3DExtras::QPhongMaterial *phongMaterial( const QgsPhongMaterialSettings &settings );
};

#endif
@@ -264,8 +264,7 @@ void QgsRuleBased3DRenderer::Rule::createHandlers( QgsVectorLayer *layer, QgsRul
}
else if ( mSymbol->type() == QLatin1String( "point" ) )
{
// TODO: point symbol
//handler = Qgs3DSymbolImpl::handlerForPoint3DSymbol( context, layer, *static_cast<QgsPoint3DSymbol *>( mSymbol.get() ) );
handler = Qgs3DSymbolImpl::handlerForPoint3DSymbol( layer, *static_cast<QgsPoint3DSymbol *>( mSymbol.get() ) );
}
else if ( mSymbol->type() == QLatin1String( "line" ) )
{
@@ -84,7 +84,7 @@ Qt3DCore::QEntity *QgsVectorLayer3DRenderer::createEntity( const Qgs3DMapSetting
if ( mSymbol->type() == QLatin1String( "polygon" ) )
return Qgs3DSymbolImpl::entityForPolygon3DSymbol( map, vl, *static_cast<QgsPolygon3DSymbol *>( mSymbol.get() ) );
else if ( mSymbol->type() == QLatin1String( "point" ) )
return new QgsPoint3DSymbolEntity( map, vl, *static_cast<QgsPoint3DSymbol *>( mSymbol.get() ) );
return Qgs3DSymbolImpl::entityForPoint3DSymbol( map, vl, *static_cast<QgsPoint3DSymbol *>( mSymbol.get() ) );
else if ( mSymbol->type() == QLatin1String( "line" ) )
return Qgs3DSymbolImpl::entityForLine3DSymbol( map, vl, *static_cast<QgsLine3DSymbol *>( mSymbol.get() ) );
else

0 comments on commit b6f7176

Please sign in to comment.
You can’t perform that action at this time.