diff --git a/src/3d/symbols/qgsline3dsymbol_p.cpp b/src/3d/symbols/qgsline3dsymbol_p.cpp index 465562d057a1..cff6d7c77638 100644 --- a/src/3d/symbols/qgsline3dsymbol_p.cpp +++ b/src/3d/symbols/qgsline3dsymbol_p.cpp @@ -45,8 +45,9 @@ class QgsBufferedLine3DSymbolHandler : public QgsFeature3DHandler { public: - QgsBufferedLine3DSymbolHandler( const QgsLine3DSymbol &symbol, const QgsFeatureIds &selectedIds ) - : mSymbol( symbol ), mSelectedIds( selectedIds ) {} + QgsBufferedLine3DSymbolHandler( const QgsLine3DSymbol *symbol, const QgsFeatureIds &selectedIds ) + : mSymbol( static_cast< QgsLine3DSymbol *>( symbol->clone() ) ) + , mSelectedIds( selectedIds ) {} bool prepare( const Qgs3DRenderContext &context, QSet &attributeNames ) override; void processFeature( QgsFeature &feature, const Qgs3DRenderContext &context ) override; @@ -67,7 +68,7 @@ class QgsBufferedLine3DSymbolHandler : public QgsFeature3DHandler void makeEntity( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context, LineData &out, bool selected ); // input specific for this class - const QgsLine3DSymbol &mSymbol; + std::unique_ptr< QgsLine3DSymbol > mSymbol; // inputs - generic QgsFeatureIds mSelectedIds; @@ -82,7 +83,7 @@ bool QgsBufferedLine3DSymbolHandler::prepare( const Qgs3DRenderContext &context, { Q_UNUSED( attributeNames ) - const QgsPhongTexturedMaterialSettings *texturedMaterialSettings = dynamic_cast< const QgsPhongTexturedMaterialSettings * >( mSymbol.material() ); + const QgsPhongTexturedMaterialSettings *texturedMaterialSettings = dynamic_cast< const QgsPhongTexturedMaterialSettings * >( mSymbol->material() ); outNormal.tessellator.reset( new QgsTessellator( context.map().origin().x(), context.map().origin().y(), true, false, false, false, texturedMaterialSettings ? texturedMaterialSettings->requiresTextureCoordinates() : false, @@ -118,12 +119,12 @@ void QgsBufferedLine3DSymbolHandler::processFeature( QgsFeature &f, const Qgs3DR const double mitreLimit = 0; QgsGeos engine( g ); - QgsAbstractGeometry *buffered = engine.buffer( mSymbol.width() / 2., nSegments, endCapStyle, joinStyle, mitreLimit ); // factory + QgsAbstractGeometry *buffered = engine.buffer( mSymbol->width() / 2., nSegments, endCapStyle, joinStyle, mitreLimit ); // factory if ( QgsWkbTypes::flatType( buffered->wkbType() ) == QgsWkbTypes::Polygon ) { QgsPolygon *polyBuffered = static_cast( buffered ); - processPolygon( polyBuffered, f.id(), mSymbol.height(), mSymbol.extrusionHeight(), context, out ); + processPolygon( polyBuffered, f.id(), mSymbol->height(), mSymbol->extrusionHeight(), context, out ); } else if ( QgsWkbTypes::flatType( buffered->wkbType() ) == QgsWkbTypes::MultiPolygon ) { @@ -131,7 +132,7 @@ void QgsBufferedLine3DSymbolHandler::processFeature( QgsFeature &f, const Qgs3DR for ( int i = 0; i < mpolyBuffered->numGeometries(); ++i ) { QgsPolygon *polyBuffered = static_cast( mpolyBuffered->polygonN( i ) )->clone(); // need to clone individual geometry parts - processPolygon( polyBuffered, f.id(), mSymbol.height(), mSymbol.extrusionHeight(), context, out ); + processPolygon( polyBuffered, f.id(), mSymbol->height(), mSymbol->extrusionHeight(), context, out ); } delete buffered; } @@ -139,7 +140,7 @@ void QgsBufferedLine3DSymbolHandler::processFeature( QgsFeature &f, const Qgs3DR void QgsBufferedLine3DSymbolHandler::processPolygon( QgsPolygon *polyBuffered, QgsFeatureId fid, float height, float extrusionHeight, const Qgs3DRenderContext &context, LineData &out ) { - Qgs3DUtils::clampAltitudes( polyBuffered, mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), height, context.map() ); + Qgs3DUtils::clampAltitudes( polyBuffered, mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), height, context.map() ); Q_ASSERT( out.tessellator->dataVerticesCount() % 3 == 0 ); uint startingTriangleIndex = static_cast( out.tessellator->dataVerticesCount() / 3 ); @@ -168,13 +169,13 @@ void QgsBufferedLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, cons QgsMaterialContext materialContext; materialContext.setIsSelected( selected ); materialContext.setSelectionColor( context.map().selectionColor() ); - Qt3DRender::QMaterial *mat = mSymbol.material()->toMaterial( QgsMaterialSettingsRenderingTechnique::Triangles, materialContext ); + Qt3DRender::QMaterial *mat = mSymbol->material()->toMaterial( QgsMaterialSettingsRenderingTechnique::Triangles, materialContext ); // extract vertex buffer data from tessellator QByteArray data( ( const char * )out.tessellator->data().constData(), out.tessellator->data().count() * sizeof( float ) ); int nVerts = data.count() / out.tessellator->stride(); - const QgsPhongTexturedMaterialSettings *texturedMaterialSettings = dynamic_cast< const QgsPhongTexturedMaterialSettings * >( mSymbol.material() ); + const QgsPhongTexturedMaterialSettings *texturedMaterialSettings = dynamic_cast< const QgsPhongTexturedMaterialSettings * >( mSymbol->material() ); QgsTessellatedPolygonGeometry *geometry = new QgsTessellatedPolygonGeometry( true, false, false, texturedMaterialSettings ? texturedMaterialSettings->requiresTextureCoordinates() : false ); @@ -203,8 +204,9 @@ void QgsBufferedLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, cons class QgsSimpleLine3DSymbolHandler : public QgsFeature3DHandler { public: - QgsSimpleLine3DSymbolHandler( const QgsLine3DSymbol &symbol, const QgsFeatureIds &selectedIds ) - : mSymbol( symbol ), mSelectedIds( selectedIds ) + QgsSimpleLine3DSymbolHandler( const QgsLine3DSymbol *symbol, const QgsFeatureIds &selectedIds ) + : mSymbol( static_cast< QgsLine3DSymbol *>( symbol->clone() ) ) + , mSelectedIds( selectedIds ) { } @@ -218,7 +220,7 @@ class QgsSimpleLine3DSymbolHandler : public QgsFeature3DHandler Qt3DExtras::QPhongMaterial *material( const QgsLine3DSymbol &symbol ) const; // input specific for this class - const QgsLine3DSymbol &mSymbol; + std::unique_ptr< QgsLine3DSymbol > mSymbol; // inputs - generic QgsFeatureIds mSelectedIds; @@ -233,8 +235,8 @@ bool QgsSimpleLine3DSymbolHandler::prepare( const Qgs3DRenderContext &context, Q { Q_UNUSED( attributeNames ) - outNormal.init( mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), &context.map() ); - outSelected.init( mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), &context.map() ); + outNormal.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->height(), &context.map() ); + outSelected.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->height(), &context.map() ); return true; } @@ -284,7 +286,7 @@ void QgsSimpleLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const QgsMaterialContext materialContext; materialContext.setIsSelected( selected ); materialContext.setSelectionColor( context.map().selectionColor() ); - Qt3DRender::QMaterial *mat = mSymbol.material()->toMaterial( QgsMaterialSettingsRenderingTechnique::Lines, materialContext ); + Qt3DRender::QMaterial *mat = mSymbol->material()->toMaterial( QgsMaterialSettingsRenderingTechnique::Lines, materialContext ); // geometry renderer @@ -313,8 +315,9 @@ void QgsSimpleLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const class QgsThickLine3DSymbolHandler : public QgsFeature3DHandler { public: - QgsThickLine3DSymbolHandler( const QgsLine3DSymbol &symbol, const QgsFeatureIds &selectedIds ) - : mSymbol( symbol ), mSelectedIds( selectedIds ) + QgsThickLine3DSymbolHandler( const QgsLine3DSymbol *symbol, const QgsFeatureIds &selectedIds ) + : mSymbol( static_cast< QgsLine3DSymbol * >( symbol->clone() ) ) + , mSelectedIds( selectedIds ) { } @@ -329,7 +332,7 @@ class QgsThickLine3DSymbolHandler : public QgsFeature3DHandler Qt3DExtras::QPhongMaterial *material( const QgsLine3DSymbol &symbol ) const; // input specific for this class - const QgsLine3DSymbol &mSymbol; + std::unique_ptr< QgsLine3DSymbol > mSymbol; // inputs - generic QgsFeatureIds mSelectedIds; @@ -346,8 +349,8 @@ bool QgsThickLine3DSymbolHandler::prepare( const Qgs3DRenderContext &context, QS outNormal.withAdjacency = true; outSelected.withAdjacency = true; - outNormal.init( mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), &context.map() ); - outSelected.init( mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), &context.map() ); + outNormal.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->height(), &context.map() ); + outSelected.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->height(), &context.map() ); return true; } @@ -396,7 +399,7 @@ void QgsThickLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const Q QgsMaterialContext materialContext; materialContext.setIsSelected( selected ); materialContext.setSelectionColor( context.map().selectionColor() ); - Qt3DRender::QMaterial *mat = mSymbol.material()->toMaterial( QgsMaterialSettingsRenderingTechnique::Lines, materialContext ); + Qt3DRender::QMaterial *mat = mSymbol->material()->toMaterial( QgsMaterialSettingsRenderingTechnique::Lines, materialContext ); if ( !mat ) { QgsSimpleLineMaterialSettings defaultMaterial; @@ -404,7 +407,7 @@ void QgsThickLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const Q } if ( QgsLineMaterial *lineMaterial = dynamic_cast< QgsLineMaterial * >( mat ) ) - lineMaterial->setLineWidth( mSymbol.width() ); + lineMaterial->setLineWidth( mSymbol->width() ); Qt3DCore::QEntity *entity = new Qt3DCore::QEntity; @@ -436,10 +439,10 @@ namespace Qgs3DSymbolImpl return nullptr; if ( lineSymbol->renderAsSimpleLines() ) - return new QgsThickLine3DSymbolHandler( *lineSymbol, layer->selectedFeatureIds() ); + return new QgsThickLine3DSymbolHandler( lineSymbol, layer->selectedFeatureIds() ); //return new QgsSimpleLine3DSymbolHandler( symbol, layer->selectedFeatureIds() ); else - return new QgsBufferedLine3DSymbolHandler( *lineSymbol, layer->selectedFeatureIds() ); + return new QgsBufferedLine3DSymbolHandler( lineSymbol, layer->selectedFeatureIds() ); } Qt3DCore::QEntity *entityForLine3DSymbol( const Qgs3DMapSettings &map, QgsVectorLayer *layer, const QgsLine3DSymbol &symbol ) diff --git a/src/3d/symbols/qgspoint3dsymbol_p.cpp b/src/3d/symbols/qgspoint3dsymbol_p.cpp index e2d3d41bf3f2..2aa34e034b57 100644 --- a/src/3d/symbols/qgspoint3dsymbol_p.cpp +++ b/src/3d/symbols/qgspoint3dsymbol_p.cpp @@ -65,8 +65,9 @@ class QgsInstancedPoint3DSymbolHandler : public QgsFeature3DHandler { public: - QgsInstancedPoint3DSymbolHandler( const QgsPoint3DSymbol &symbol, const QgsFeatureIds &selectedIds ) - : mSymbol( symbol ), mSelectedIds( selectedIds ) {} + QgsInstancedPoint3DSymbolHandler( const QgsPoint3DSymbol *symbol, const QgsFeatureIds &selectedIds ) + : mSymbol( static_cast< QgsPoint3DSymbol *>( symbol->clone() ) ) + , mSelectedIds( selectedIds ) {} bool prepare( const Qgs3DRenderContext &context, QSet &attributeNames ) override; void processFeature( QgsFeature &feature, const Qgs3DRenderContext &context ) override; @@ -74,8 +75,8 @@ class QgsInstancedPoint3DSymbolHandler : public QgsFeature3DHandler private: - static Qt3DRender::QMaterial *material( const QgsPoint3DSymbol &symbol ); - static Qt3DRender::QGeometryRenderer *renderer( const QgsPoint3DSymbol &symbol, const QVector &positions ); + static Qt3DRender::QMaterial *material( const QgsPoint3DSymbol *symbol ); + static Qt3DRender::QGeometryRenderer *renderer( const QgsPoint3DSymbol *symbol, const QVector &positions ); static Qt3DRender::QGeometry *symbolGeometry( QgsPoint3DSymbol::Shape shape, const QVariantMap &shapeProperties ); //! temporary data we will pass to the tessellator @@ -87,7 +88,7 @@ class QgsInstancedPoint3DSymbolHandler : public QgsFeature3DHandler void makeEntity( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context, PointData &out, bool selected ); // input specific for this class - const QgsPoint3DSymbol &mSymbol; + std::unique_ptr< QgsPoint3DSymbol > mSymbol; // inputs - generic QgsFeatureIds mSelectedIds; @@ -111,7 +112,7 @@ void QgsInstancedPoint3DSymbolHandler::processFeature( QgsFeature &feature, cons if ( feature.geometry().isNull() ) return; - Qgs3DUtils::extractPointPositions( feature, context.map(), mSymbol.altitudeClamping(), out.positions ); + Qgs3DUtils::extractPointPositions( feature, context.map(), mSymbol->altitudeClamping(), out.positions ); } void QgsInstancedPoint3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context ) @@ -123,7 +124,7 @@ void QgsInstancedPoint3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, cons updateZRangeFromPositions( outSelected.positions ); // the elevation offset is applied in the vertex shader so let's account for it as well - float symbolHeight = mSymbol.transform().data()[13]; + float symbolHeight = mSymbol->transform().data()[13]; mZMin += symbolHeight; mZMax += symbolHeight; } @@ -131,7 +132,7 @@ void QgsInstancedPoint3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, cons void QgsInstancedPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context, PointData &out, bool selected ) { // build the default material - Qt3DRender::QMaterial *mat = material( mSymbol ); + Qt3DRender::QMaterial *mat = material( mSymbol.get() ); if ( selected ) { @@ -147,7 +148,7 @@ void QgsInstancedPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, co // build the entity Qt3DCore::QEntity *entity = new Qt3DCore::QEntity; - entity->addComponent( renderer( mSymbol, out.positions ) ); + entity->addComponent( renderer( mSymbol.get(), out.positions ) ); entity->addComponent( mat ); entity->setParent( parent ); @@ -157,7 +158,7 @@ void QgsInstancedPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, co -Qt3DRender::QMaterial *QgsInstancedPoint3DSymbolHandler::material( const QgsPoint3DSymbol &symbol ) +Qt3DRender::QMaterial *QgsInstancedPoint3DSymbolHandler::material( const QgsPoint3DSymbol *symbol ) { Qt3DRender::QFilterKey *filterKey = new Qt3DRender::QFilterKey; filterKey->setName( QStringLiteral( "renderingStyle" ) ); @@ -181,7 +182,7 @@ Qt3DRender::QMaterial *QgsInstancedPoint3DSymbolHandler::material( const QgsPoin technique->graphicsApiFilter()->setMajorVersion( 3 ); technique->graphicsApiFilter()->setMinorVersion( 2 ); - QMatrix4x4 transformMatrix = symbol.transform(); + QMatrix4x4 transformMatrix = symbol->transform(); QMatrix3x3 normalMatrix = transformMatrix.normalMatrix(); // transponed inverse of 3x3 sub-matrix // QMatrix3x3 is not supported for passing to shaders, so we pass QMatrix4x4 @@ -205,7 +206,7 @@ Qt3DRender::QMaterial *QgsInstancedPoint3DSymbolHandler::material( const QgsPoin effect->addParameter( paramInst ); effect->addParameter( paramInstNormal ); - symbol.material()->addParametersToEffect( effect ); + symbol->material()->addParametersToEffect( effect ); Qt3DRender::QMaterial *material = new Qt3DRender::QMaterial; material->setEffect( effect ); @@ -213,7 +214,7 @@ Qt3DRender::QMaterial *QgsInstancedPoint3DSymbolHandler::material( const QgsPoin return material; } -Qt3DRender::QGeometryRenderer *QgsInstancedPoint3DSymbolHandler::renderer( const QgsPoint3DSymbol &symbol, const QVector &positions ) +Qt3DRender::QGeometryRenderer *QgsInstancedPoint3DSymbolHandler::renderer( const QgsPoint3DSymbol *symbol, const QVector &positions ) { int count = positions.count(); int byteCount = positions.count() * sizeof( QVector3D ); @@ -239,7 +240,7 @@ Qt3DRender::QGeometryRenderer *QgsInstancedPoint3DSymbolHandler::renderer( const instanceDataAttribute->setCount( count ); instanceDataAttribute->setByteStride( 3 * sizeof( float ) ); - Qt3DRender::QGeometry *geometry = symbolGeometry( symbol.shape(), symbol.shapeProperties() ); + Qt3DRender::QGeometry *geometry = symbolGeometry( symbol->shape(), symbol->shapeProperties() ); geometry->addAttribute( instanceDataAttribute ); geometry->setBoundingVolumePositionAttribute( instanceDataAttribute ); @@ -341,8 +342,9 @@ Qt3DRender::QGeometry *QgsInstancedPoint3DSymbolHandler::symbolGeometry( QgsPoin class QgsModelPoint3DSymbolHandler : public QgsFeature3DHandler { public: - QgsModelPoint3DSymbolHandler( const QgsPoint3DSymbol &symbol, const QgsFeatureIds &selectedIds ) - : mSymbol( symbol ), mSelectedIds( selectedIds ) {} + QgsModelPoint3DSymbolHandler( const QgsPoint3DSymbol *symbol, const QgsFeatureIds &selectedIds ) + : mSymbol( static_cast< QgsPoint3DSymbol * >( symbol->clone() ) ) + , mSelectedIds( selectedIds ) {} bool prepare( const Qgs3DRenderContext &context, QSet &attributeNames ) override; void processFeature( QgsFeature &feature, const Qgs3DRenderContext &context ) override; @@ -350,9 +352,9 @@ class QgsModelPoint3DSymbolHandler : public QgsFeature3DHandler private: - static void addSceneEntities( const Qgs3DMapSettings &map, const QVector &positions, const QgsPoint3DSymbol &symbol, Qt3DCore::QEntity *parent ); - static void addMeshEntities( const Qgs3DMapSettings &map, const QVector &positions, const QgsPoint3DSymbol &symbol, Qt3DCore::QEntity *parent, bool are_selected ); - static Qt3DCore::QTransform *transform( QVector3D position, const QgsPoint3DSymbol &symbol ); + static void addSceneEntities( const Qgs3DMapSettings &map, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent ); + static void addMeshEntities( const Qgs3DMapSettings &map, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent, bool are_selected ); + static Qt3DCore::QTransform *transform( QVector3D position, const QgsPoint3DSymbol *symbol ); //! temporary data we will pass to the tessellator struct PointData @@ -363,7 +365,7 @@ class QgsModelPoint3DSymbolHandler : public QgsFeature3DHandler void makeEntity( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context, PointData &out, bool selected ); // input specific for this class - const QgsPoint3DSymbol &mSymbol; + std::unique_ptr< QgsPoint3DSymbol > mSymbol; // inputs - generic QgsFeatureIds mSelectedIds; @@ -386,7 +388,7 @@ void QgsModelPoint3DSymbolHandler::processFeature( QgsFeature &feature, const Qg if ( feature.geometry().isNull() ) return; - Qgs3DUtils::extractPointPositions( feature, context.map(), mSymbol.altitudeClamping(), out.positions ); + Qgs3DUtils::extractPointPositions( feature, context.map(), mSymbol->altitudeClamping(), out.positions ); } void QgsModelPoint3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context ) @@ -398,7 +400,7 @@ void QgsModelPoint3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, const Qg updateZRangeFromPositions( outSelected.positions ); // the elevation offset is applied separately in QTransform added to sub-entities - float symbolHeight = mSymbol.transform().data()[13]; + float symbolHeight = mSymbol->transform().data()[13]; mZMin += symbolHeight; mZMax += symbolHeight; } @@ -407,29 +409,29 @@ void QgsModelPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const { if ( selected ) { - addMeshEntities( context.map(), out.positions, mSymbol, parent, true ); + addMeshEntities( context.map(), out.positions, mSymbol.get(), parent, true ); } else { - if ( mSymbol.shapeProperties()[QStringLiteral( "overwriteMaterial" )].toBool() ) + if ( mSymbol->shapeProperties()[QStringLiteral( "overwriteMaterial" )].toBool() ) { - addMeshEntities( context.map(), out.positions, mSymbol, parent, false ); + addMeshEntities( context.map(), out.positions, mSymbol.get(), parent, false ); } else { - addSceneEntities( context.map(), out.positions, mSymbol, parent ); + addSceneEntities( context.map(), out.positions, mSymbol.get(), parent ); } } } -void QgsModelPoint3DSymbolHandler::addSceneEntities( const Qgs3DMapSettings &map, const QVector &positions, const QgsPoint3DSymbol &symbol, Qt3DCore::QEntity *parent ) +void QgsModelPoint3DSymbolHandler::addSceneEntities( const Qgs3DMapSettings &map, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent ) { Q_UNUSED( map ) for ( const QVector3D &position : positions ) { - const QString source = QgsApplication::instance()->sourceCache()->localFilePath( symbol.shapeProperties()[QStringLiteral( "model" )].toString() ); + const QString source = QgsApplication::instance()->sourceCache()->localFilePath( symbol->shapeProperties()[QStringLiteral( "model" )].toString() ); // if the source is remote, the Qgs3DMapScene will take care of refreshing this 3D symbol when the source is fetched if ( !source.isEmpty() ) { @@ -450,18 +452,18 @@ void QgsModelPoint3DSymbolHandler::addSceneEntities( const Qgs3DMapSettings &map } } -void QgsModelPoint3DSymbolHandler::addMeshEntities( const Qgs3DMapSettings &map, const QVector &positions, const QgsPoint3DSymbol &symbol, Qt3DCore::QEntity *parent, bool are_selected ) +void QgsModelPoint3DSymbolHandler::addMeshEntities( const Qgs3DMapSettings &map, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent, bool are_selected ) { // build the default material QgsMaterialContext materialContext; materialContext.setIsSelected( are_selected ); materialContext.setSelectionColor( map.selectionColor() ); - Qt3DRender::QMaterial *mat = symbol.material()->toMaterial( QgsMaterialSettingsRenderingTechnique::Triangles, materialContext ); + Qt3DRender::QMaterial *mat = symbol->material()->toMaterial( QgsMaterialSettingsRenderingTechnique::Triangles, materialContext ); // get nodes for ( const QVector3D &position : positions ) { - const QString source = QgsApplication::instance()->sourceCache()->localFilePath( symbol.shapeProperties()[QStringLiteral( "model" )].toString() ); + const QString source = QgsApplication::instance()->sourceCache()->localFilePath( symbol->shapeProperties()[QStringLiteral( "model" )].toString() ); if ( !source.isEmpty() ) { // build the entity @@ -482,10 +484,10 @@ void QgsModelPoint3DSymbolHandler::addMeshEntities( const Qgs3DMapSettings &map, } } -Qt3DCore::QTransform *QgsModelPoint3DSymbolHandler::transform( QVector3D position, const QgsPoint3DSymbol &symbol ) +Qt3DCore::QTransform *QgsModelPoint3DSymbolHandler::transform( QVector3D position, const QgsPoint3DSymbol *symbol ) { Qt3DCore::QTransform *tr = new Qt3DCore::QTransform; - tr->setMatrix( symbol.transform() ); + tr->setMatrix( symbol->transform() ); tr->setTranslation( position + tr->translation() ); return tr; } @@ -497,8 +499,9 @@ Qt3DCore::QTransform *QgsModelPoint3DSymbolHandler::transform( QVector3D positio class QgsPoint3DBillboardSymbolHandler : public QgsFeature3DHandler { public: - QgsPoint3DBillboardSymbolHandler( const QgsPoint3DSymbol &symbol, const QgsFeatureIds &selectedIds ) - : mSymbol( symbol ), mSelectedIds( selectedIds ) {} + QgsPoint3DBillboardSymbolHandler( const QgsPoint3DSymbol *symbol, const QgsFeatureIds &selectedIds ) + : mSymbol( static_cast< QgsPoint3DSymbol * >( symbol->clone() ) ) + , mSelectedIds( selectedIds ) {} bool prepare( const Qgs3DRenderContext &context, QSet &attributeNames ) override; void processFeature( QgsFeature &feature, const Qgs3DRenderContext &context ) override; @@ -515,7 +518,7 @@ class QgsPoint3DBillboardSymbolHandler : public QgsFeature3DHandler void makeEntity( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context, PointData &out, bool selected ); // input specific for this class - const QgsPoint3DSymbol &mSymbol; + std::unique_ptr< QgsPoint3DSymbol > mSymbol; // inputs - generic QgsFeatureIds mSelectedIds; @@ -538,7 +541,7 @@ void QgsPoint3DBillboardSymbolHandler::processFeature( QgsFeature &feature, cons if ( feature.geometry().isNull() ) return; - Qgs3DUtils::extractPointPositions( feature, context.map(), mSymbol.altitudeClamping(), out.positions ); + Qgs3DUtils::extractPointPositions( feature, context.map(), mSymbol->altitudeClamping(), out.positions ); } void QgsPoint3DBillboardSymbolHandler::finalize( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context ) @@ -550,7 +553,7 @@ void QgsPoint3DBillboardSymbolHandler::finalize( Qt3DCore::QEntity *parent, cons updateZRangeFromPositions( outSelected.positions ); // the elevation offset is applied externally through a QTransform of QEntity so let's account for it - float billboardHeight = mSymbol.transform().data()[13]; + float billboardHeight = mSymbol->transform().data()[13]; mZMin += billboardHeight; mZMax += billboardHeight; } @@ -569,7 +572,7 @@ void QgsPoint3DBillboardSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, co // Billboard Material QgsPoint3DBillboardMaterial *billboardMaterial = new QgsPoint3DBillboardMaterial(); - QgsMarkerSymbol *symbol = mSymbol.billboardSymbol(); + QgsMarkerSymbol *symbol = mSymbol->billboardSymbol(); if ( symbol ) { @@ -582,7 +585,7 @@ void QgsPoint3DBillboardSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, co // Billboard Transform Qt3DCore::QTransform *billboardTransform = new Qt3DCore::QTransform(); - billboardTransform->setMatrix( mSymbol.billboardTransform() ); + billboardTransform->setMatrix( mSymbol->billboardTransform() ); // Build the entity Qt3DCore::QEntity *entity = new Qt3DCore::QEntity; @@ -607,12 +610,12 @@ namespace Qgs3DSymbolImpl return nullptr; if ( pointSymbol->shape() == QgsPoint3DSymbol::Model ) - return new QgsModelPoint3DSymbolHandler( *pointSymbol, layer->selectedFeatureIds() ); + return new QgsModelPoint3DSymbolHandler( pointSymbol, layer->selectedFeatureIds() ); // Add proper handler for billboard else if ( pointSymbol->shape() == QgsPoint3DSymbol::Billboard ) - return new QgsPoint3DBillboardSymbolHandler( *pointSymbol, layer->selectedFeatureIds() ); + return new QgsPoint3DBillboardSymbolHandler( pointSymbol, layer->selectedFeatureIds() ); else - return new QgsInstancedPoint3DSymbolHandler( *pointSymbol, layer->selectedFeatureIds() ); + return new QgsInstancedPoint3DSymbolHandler( pointSymbol, layer->selectedFeatureIds() ); } Qt3DCore::QEntity *entityForPoint3DSymbol( const Qgs3DMapSettings &map, QgsVectorLayer *layer, const QgsPoint3DSymbol &symbol ) diff --git a/src/3d/symbols/qgspolygon3dsymbol_p.cpp b/src/3d/symbols/qgspolygon3dsymbol_p.cpp index 0dbc975bd76d..90bd06fba85f 100644 --- a/src/3d/symbols/qgspolygon3dsymbol_p.cpp +++ b/src/3d/symbols/qgspolygon3dsymbol_p.cpp @@ -50,8 +50,9 @@ class QgsPolygon3DSymbolHandler : public QgsFeature3DHandler { public: - QgsPolygon3DSymbolHandler( const QgsPolygon3DSymbol &symbol, const QgsFeatureIds &selectedIds ) - : mSymbol( symbol ), mSelectedIds( selectedIds ) {} + QgsPolygon3DSymbolHandler( const QgsPolygon3DSymbol *symbol, const QgsFeatureIds &selectedIds ) + : mSymbol( static_cast< QgsPolygon3DSymbol *>( symbol->clone() ) ) + , mSelectedIds( selectedIds ) {} bool prepare( const Qgs3DRenderContext &context, QSet &attributeNames ) override; void processFeature( QgsFeature &feature, const Qgs3DRenderContext &context ) override; @@ -69,10 +70,10 @@ class QgsPolygon3DSymbolHandler : public QgsFeature3DHandler void processPolygon( QgsPolygon *polyClone, QgsFeatureId fid, float height, float extrusionHeight, const Qgs3DRenderContext &context, PolygonData &out ); void makeEntity( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context, PolygonData &out, bool selected ); - Qt3DRender::QMaterial *material( const QgsPolygon3DSymbol &symbol, bool isSelected, const Qgs3DRenderContext &context ) const; + Qt3DRender::QMaterial *material( const QgsPolygon3DSymbol *symbol, bool isSelected, const Qgs3DRenderContext &context ) const; // input specific for this class - const QgsPolygon3DSymbol &mSymbol; + std::unique_ptr< QgsPolygon3DSymbol > mSymbol; // inputs - generic QgsFeatureIds mSelectedIds; @@ -87,28 +88,28 @@ class QgsPolygon3DSymbolHandler : public QgsFeature3DHandler bool QgsPolygon3DSymbolHandler::prepare( const Qgs3DRenderContext &context, QSet &attributeNames ) { outEdges.withAdjacency = true; - outEdges.init( mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), 0, &context.map() ); + outEdges.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), 0, &context.map() ); - const QgsPhongTexturedMaterialSettings *texturedMaterialSettings = dynamic_cast< const QgsPhongTexturedMaterialSettings * >( mSymbol.material() ); + const QgsPhongTexturedMaterialSettings *texturedMaterialSettings = dynamic_cast< const QgsPhongTexturedMaterialSettings * >( mSymbol->material() ); - outNormal.tessellator.reset( new QgsTessellator( context.map().origin().x(), context.map().origin().y(), true, mSymbol.invertNormals(), mSymbol.addBackFaces(), false, + outNormal.tessellator.reset( new QgsTessellator( context.map().origin().x(), context.map().origin().y(), true, mSymbol->invertNormals(), mSymbol->addBackFaces(), false, texturedMaterialSettings && texturedMaterialSettings->requiresTextureCoordinates(), - mSymbol.renderedFacade(), + mSymbol->renderedFacade(), texturedMaterialSettings ? texturedMaterialSettings->textureRotation() : 0 ) ); - outSelected.tessellator.reset( new QgsTessellator( context.map().origin().x(), context.map().origin().y(), true, mSymbol.invertNormals(), - mSymbol.addBackFaces(), false, + outSelected.tessellator.reset( new QgsTessellator( context.map().origin().x(), context.map().origin().y(), true, mSymbol->invertNormals(), + mSymbol->addBackFaces(), false, texturedMaterialSettings && texturedMaterialSettings->requiresTextureCoordinates(), - mSymbol.renderedFacade(), + mSymbol->renderedFacade(), texturedMaterialSettings ? texturedMaterialSettings->textureRotation() : 0 ) ); - QSet attrs = mSymbol.dataDefinedProperties().referencedFields( context.expressionContext() ); + QSet attrs = mSymbol->dataDefinedProperties().referencedFields( context.expressionContext() ); attributeNames.unite( attrs ); return true; } void QgsPolygon3DSymbolHandler::processPolygon( QgsPolygon *polyClone, QgsFeatureId fid, float height, float extrusionHeight, const Qgs3DRenderContext &context, PolygonData &out ) { - if ( mSymbol.edgesEnabled() ) + if ( mSymbol->edgesEnabled() ) { // add edges before the polygon gets the Z values modified because addLineString() does its own altitude handling outEdges.addLineString( *static_cast( polyClone->exteriorRing() ), height ); @@ -130,7 +131,7 @@ void QgsPolygon3DSymbolHandler::processPolygon( QgsPolygon *polyClone, QgsFeatur } } - Qgs3DUtils::clampAltitudes( polyClone, mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), height, context.map() ); + Qgs3DUtils::clampAltitudes( polyClone, mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), height, context.map() ); Q_ASSERT( out.tessellator->dataVerticesCount() % 3 == 0 ); uint startingTriangleIndex = static_cast( out.tessellator->dataVerticesCount() / 3 ); @@ -155,12 +156,12 @@ void QgsPolygon3DSymbolHandler::processFeature( QgsFeature &f, const Qgs3DRender const QgsAbstractGeometry *g = geom.constGet(); - const QgsPropertyCollection &ddp = mSymbol.dataDefinedProperties(); + const QgsPropertyCollection &ddp = mSymbol->dataDefinedProperties(); bool hasDDHeight = ddp.isActive( QgsAbstract3DSymbol::PropertyHeight ); bool hasDDExtrusion = ddp.isActive( QgsAbstract3DSymbol::PropertyExtrusionHeight ); - float height = mSymbol.height(); - float extrusionHeight = mSymbol.extrusionHeight(); + float height = mSymbol->height(); + float extrusionHeight = mSymbol->extrusionHeight(); if ( hasDDHeight ) height = ddp.valueAsDouble( QgsAbstract3DSymbol::PropertyHeight, context.expressionContext(), height ); if ( hasDDExtrusion ) @@ -206,11 +207,11 @@ void QgsPolygon3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, const Qgs3D mZMax = std::max( outNormal.tessellator->zMaximum(), outSelected.tessellator->zMaximum() ); // add entity for edges - if ( mSymbol.edgesEnabled() && !outEdges.indexes.isEmpty() ) + if ( mSymbol->edgesEnabled() && !outEdges.indexes.isEmpty() ) { QgsLineMaterial *mat = new QgsLineMaterial; - mat->setLineColor( mSymbol.edgeColor() ); - mat->setLineWidth( mSymbol.edgeWidth() ); + mat->setLineColor( mSymbol->edgeColor() ); + mat->setLineWidth( mSymbol->edgeWidth() ); Qt3DCore::QEntity *entity = new Qt3DCore::QEntity; @@ -235,15 +236,15 @@ void QgsPolygon3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const Qgs if ( out.tessellator->dataVerticesCount() == 0 ) return; // nothing to show - no need to create the entity - Qt3DRender::QMaterial *mat = material( mSymbol, selected, context ); + Qt3DRender::QMaterial *mat = material( mSymbol.get(), selected, context ); // extract vertex buffer data from tessellator QByteArray data( ( const char * )out.tessellator->data().constData(), out.tessellator->data().count() * sizeof( float ) ); int nVerts = data.count() / out.tessellator->stride(); - const QgsPhongTexturedMaterialSettings *texturedMaterialSettings = dynamic_cast< const QgsPhongTexturedMaterialSettings * >( mSymbol.material() ); + const QgsPhongTexturedMaterialSettings *texturedMaterialSettings = dynamic_cast< const QgsPhongTexturedMaterialSettings * >( mSymbol->material() ); - QgsTessellatedPolygonGeometry *geometry = new QgsTessellatedPolygonGeometry( true, mSymbol.invertNormals(), mSymbol.addBackFaces(), + QgsTessellatedPolygonGeometry *geometry = new QgsTessellatedPolygonGeometry( true, mSymbol->invertNormals(), mSymbol->addBackFaces(), texturedMaterialSettings && texturedMaterialSettings->requiresTextureCoordinates() ); geometry->setData( data, nVerts, out.triangleIndexFids, out.triangleIndexStartingIndices ); @@ -291,14 +292,14 @@ static void applyCullingMode( Qgs3DTypes::CullingMode cullingMode, Qt3DRender::Q } } -Qt3DRender::QMaterial *QgsPolygon3DSymbolHandler::material( const QgsPolygon3DSymbol &symbol, bool isSelected, const Qgs3DRenderContext &context ) const +Qt3DRender::QMaterial *QgsPolygon3DSymbolHandler::material( const QgsPolygon3DSymbol *symbol, bool isSelected, const Qgs3DRenderContext &context ) const { QgsMaterialContext materialContext; materialContext.setIsSelected( isSelected ); materialContext.setSelectionColor( context.map().selectionColor() ); - Qt3DRender::QMaterial *material = symbol.material()->toMaterial( QgsMaterialSettingsRenderingTechnique::Triangles, materialContext ); - applyCullingMode( symbol.cullingMode(), material ); + Qt3DRender::QMaterial *material = symbol->material()->toMaterial( QgsMaterialSettingsRenderingTechnique::Triangles, materialContext ); + applyCullingMode( symbol->cullingMode(), material ); return material; } @@ -316,7 +317,7 @@ namespace Qgs3DSymbolImpl if ( !polygonSymbol ) return nullptr; - return new QgsPolygon3DSymbolHandler( *polygonSymbol, layer->selectedFeatureIds() ); + return new QgsPolygon3DSymbolHandler( polygonSymbol, layer->selectedFeatureIds() ); } Qt3DCore::QEntity *entityForPolygon3DSymbol( const Qgs3DMapSettings &map, QgsVectorLayer *layer, const QgsPolygon3DSymbol &symbol )