Skip to content
Permalink
Browse files
[3d] Fix rendering of curved lines using simple line renderer
  • Loading branch information
nyalldawson committed May 21, 2021
1 parent 59a6217 commit 700390abff6928636de010c49746a10129c215eb
@@ -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<const QgsLineString *>( g ) )
{
out.addLineString( *ls );
@@ -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;
@@ -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<QgsPoint> 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<QgsMapLayer *>() << 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();

0 comments on commit 700390a

Please sign in to comment.