diff --git a/src/3d/symbols/qgsline3dsymbol_p.cpp b/src/3d/symbols/qgsline3dsymbol_p.cpp index 14c81b4f27a0..0088aeba2fdb 100644 --- a/src/3d/symbols/qgsline3dsymbol_p.cpp +++ b/src/3d/symbols/qgsline3dsymbol_p.cpp @@ -375,7 +375,12 @@ void QgsThickLine3DSymbolHandler::processFeature( const QgsFeature &f, const Qgs QgsLineVertexData &out = mSelectedIds.contains( f.id() ) ? outSelected : outNormal; QgsGeometry geom = f.geometry(); + // segmentize curved geometries if necessary + if ( QgsWkbTypes::isCurvedType( geom.constGet()->wkbType() ) ) + geom = QgsGeometry( geom.constGet()->segmentize() ); + const QgsAbstractGeometry *g = geom.constGet(); + if ( const QgsLineString *ls = qgsgeometry_cast( g ) ) { out.addLineString( *ls ); diff --git a/src/3d/symbols/qgslinevertexdata_p.cpp b/src/3d/symbols/qgslinevertexdata_p.cpp index c438caad2aa4..a9d1987a2325 100644 --- a/src/3d/symbols/qgslinevertexdata_p.cpp +++ b/src/3d/symbols/qgslinevertexdata_p.cpp @@ -125,7 +125,6 @@ void QgsLineVertexData::addLineString( const QgsLineString &lineString, float ex indexes << 0; // add primitive restart } - void QgsLineVertexData::addVerticalLines( const QgsLineString &lineString, float verticalLength, float extraHeightOffset ) { QgsPoint centroid; diff --git a/tests/src/3d/testqgs3drendering.cpp b/tests/src/3d/testqgs3drendering.cpp index bf33996f212e..2ceb2597900f 100644 --- a/tests/src/3d/testqgs3drendering.cpp +++ b/tests/src/3d/testqgs3drendering.cpp @@ -74,6 +74,7 @@ class TestQgs3DRendering : public QObject void testExtrudedPolygonsDataDefined(); void testPolygonsEdges(); void testLineRendering(); + void testLineRenderingCurved(); void testBufferedLineRendering(); void testBufferedLineRenderingWidth(); void testMapTheme(); @@ -564,6 +565,63 @@ void TestQgs3DRendering::testLineRendering() delete layerLines; } +void TestQgs3DRendering::testLineRenderingCurved() +{ + // test rendering of compound curve lines works + QgsRectangle fullExtent( 0, 0, 1000, 1000 ); + + QgsVectorLayer *layerLines = new QgsVectorLayer( "CompoundCurve?crs=EPSG:27700", "lines", "memory" ); + + QgsLine3DSymbol *lineSymbol = new QgsLine3DSymbol; + lineSymbol->setRenderAsSimpleLines( true ); + lineSymbol->setWidth( 10 ); + QgsSimpleLineMaterialSettings mat; + mat.setAmbient( Qt::red ); + lineSymbol->setMaterial( mat.clone() ); + layerLines->setRenderer3D( new QgsVectorLayer3DRenderer( lineSymbol ) ); + + QVector pts; + pts << QgsPoint( 0, 0, 10 ) << QgsPoint( 0, 1000, 10 ) << QgsPoint( 1000, 1000, 10 ) << QgsPoint( 1000, 0, 10 ); + std::unique_ptr< QgsCompoundCurve > curve = std::make_unique< QgsCompoundCurve >(); + curve->addCurve( new QgsLineString( pts ) ); + pts.clear(); + pts << QgsPoint( 1000, 0, 10 ) << QgsPoint( 1000, 0, 500 ) << QgsPoint( 1000, 1000, 500 ) << QgsPoint( 0, 1000, 500 ) << QgsPoint( 0, 0, 500 ); + curve->addCurve( new QgsLineString( pts ) ); + + QgsFeature f1( layerLines->fields() ); + f1.setGeometry( QgsGeometry( std::move( curve ) ) ); + QgsFeatureList flist; + flist << f1; + layerLines->dataProvider()->addFeatures( flist ); + + Qgs3DMapSettings *map = new Qgs3DMapSettings; + map->setCrs( mProject->crs() ); + map->setOrigin( QgsVector3D( fullExtent.center().x(), fullExtent.center().y(), 0 ) ); + map->setLayers( QList() << layerLines ); + + QgsFlatTerrainGenerator *flatTerrain = new QgsFlatTerrainGenerator; + flatTerrain->setCrs( map->crs() ); + flatTerrain->setExtent( fullExtent ); + map->setTerrainGenerator( flatTerrain ); + + QgsOffscreen3DEngine engine; + Qgs3DMapScene *scene = new Qgs3DMapScene( *map, &engine ); + engine.setRootEntity( scene ); + + // look from the top + scene->cameraController()->setLookingAtPoint( QgsVector3D( 0, 0, 0 ), 2500, 0, 0 ); + + // When running the test on Travis, it would initially return empty rendered image. + // Capturing the initial image and throwing it away fixes that. Hopefully we will + // find a better fix in the future. + Qgs3DUtils::captureSceneImage( engine, scene ); + + QImage img = Qgs3DUtils::captureSceneImage( engine, scene ); + QVERIFY( renderCheck( "line_rendering_1", img, 40 ) ); + + delete layerLines; +} + void TestQgs3DRendering::testBufferedLineRendering() { QgsRectangle fullExtent = mLayerDtm->extent();