Skip to content

Commit

Permalink
Introduce concept of 3D symbols + addition of "single symbol" vector …
Browse files Browse the repository at this point in the history
…3D renderer
  • Loading branch information
wonder-sk committed Sep 15, 2017
1 parent 76f4f69 commit b9dd6bc
Show file tree
Hide file tree
Showing 13 changed files with 395 additions and 322 deletions.
2 changes: 2 additions & 0 deletions src/3d/CMakeLists.txt
Expand Up @@ -3,6 +3,7 @@

SET(QGIS_3D_SRCS
abstract3drenderer.cpp
abstract3dsymbol.cpp
cameracontroller.cpp
lineentity.cpp
map3d.cpp
Expand Down Expand Up @@ -63,6 +64,7 @@ QT5_ADD_RESOURCES(QGIS_3D_RCC_SRCS shaders.qrc)
SET(QGIS_3D_HDRS
aabb.h
abstract3drenderer.h
abstract3dsymbol.h
cameracontroller.h
lineentity.h
map3d.h
Expand Down
213 changes: 51 additions & 162 deletions src/3d/abstract3drenderer.cpp
@@ -1,5 +1,6 @@
#include "abstract3drenderer.h"

#include "abstract3dsymbol.h"
#include "lineentity.h"
#include "pointentity.h"
#include "polygonentity.h"
Expand All @@ -8,206 +9,94 @@
#include "qgsxmlutils.h"


// ---------------

PolygonRenderer::PolygonRenderer()
: altClamping( AltClampRelative )
, altBinding( AltBindCentroid )
, height( 0 )
, extrusionHeight( 0 )
{
}

void PolygonRenderer::setLayer( QgsVectorLayer *layer )
{
layerRef = QgsMapLayerRef( layer );
}

QgsVectorLayer *PolygonRenderer::layer() const
{
return qobject_cast<QgsVectorLayer *>( layerRef.layer );
}

Abstract3DRenderer *PolygonRenderer::clone() const
{
return new PolygonRenderer( *this );
}

Qt3DCore::QEntity *PolygonRenderer::createEntity( const Map3D &map ) const
{
return new PolygonEntity( map, *this );
}

void PolygonRenderer::writeXml( QDomElement &elem ) const
{
QDomDocument doc = elem.ownerDocument();

QDomElement elemDataProperties = doc.createElement( "data" );
elemDataProperties.setAttribute( "layer", layerRef.layerId );
elemDataProperties.setAttribute( "alt-clamping", Utils::altClampingToString( altClamping ) );
elemDataProperties.setAttribute( "alt-binding", Utils::altBindingToString( altBinding ) );
elemDataProperties.setAttribute( "height", height );
elemDataProperties.setAttribute( "extrusion-height", extrusionHeight );
elem.appendChild( elemDataProperties );

QDomElement elemMaterial = doc.createElement( "material" );
material.writeXml( elemMaterial );
elem.appendChild( elemMaterial );
}

void PolygonRenderer::readXml( const QDomElement &elem )
VectorLayer3DRenderer::VectorLayer3DRenderer( Abstract3DSymbol *s )
: mSymbol( s )
{
QDomElement elemDataProperties = elem.firstChildElement( "data" );
layerRef = QgsMapLayerRef( elemDataProperties.attribute( "layer" ) );
altClamping = Utils::altClampingFromString( elemDataProperties.attribute( "alt-clamping" ) );
altBinding = Utils::altBindingFromString( elemDataProperties.attribute( "alt-binding" ) );
height = elemDataProperties.attribute( "height" ).toFloat();
extrusionHeight = elemDataProperties.attribute( "extrusion-height" ).toFloat();

QDomElement elemMaterial = elem.firstChildElement( "material" );
material.readXml( elemMaterial );
}

void PolygonRenderer::resolveReferences( const QgsProject &project )
VectorLayer3DRenderer::~VectorLayer3DRenderer()
{
layerRef.setLayer( project.mapLayer( layerRef.layerId ) );
}

// ---------------

PointRenderer::PointRenderer()
: height( 0 )
Abstract3DRenderer *VectorLayer3DRenderer::clone() const
{
VectorLayer3DRenderer *r = new VectorLayer3DRenderer( mSymbol ? mSymbol->clone() : nullptr );
r->layerRef = layerRef;
return r;
}

void PointRenderer::setLayer( QgsVectorLayer *layer )
void VectorLayer3DRenderer::setLayer( QgsVectorLayer *layer )
{
layerRef = QgsMapLayerRef( layer );
}

QgsVectorLayer *PointRenderer::layer() const
QgsVectorLayer *VectorLayer3DRenderer::layer() const
{
return qobject_cast<QgsVectorLayer *>( layerRef.layer );
}

Abstract3DRenderer *PointRenderer::clone() const
{
return new PointRenderer( *this );
}

Qt3DCore::QEntity *PointRenderer::createEntity( const Map3D &map ) const
void VectorLayer3DRenderer::setSymbol( Abstract3DSymbol *symbol )
{
return new PointEntity( map, *this );
mSymbol.reset( symbol );
}

void PointRenderer::writeXml( QDomElement &elem ) const
const Abstract3DSymbol *VectorLayer3DRenderer::symbol() const
{
QDomDocument doc = elem.ownerDocument();

QDomElement elemDataProperties = doc.createElement( "data" );
elemDataProperties.setAttribute( "layer", layerRef.layerId );
elemDataProperties.setAttribute( "height", height );
elem.appendChild( elemDataProperties );

QDomElement elemMaterial = doc.createElement( "material" );
material.writeXml( elemMaterial );
elem.appendChild( elemMaterial );

QDomElement elemShapeProperties = doc.createElement( "shape-properties" );
elemShapeProperties.appendChild( QgsXmlUtils::writeVariant( shapeProperties, doc ) );
elem.appendChild( elemShapeProperties );

QDomElement elemTransform = doc.createElement( "transform" );
elemTransform.setAttribute( "matrix", Utils::matrix4x4toString( transform ) );
elem.appendChild( elemTransform );
}

void PointRenderer::readXml( const QDomElement &elem )
{
QDomElement elemDataProperties = elem.firstChildElement( "data" );
layerRef = QgsMapLayerRef( elemDataProperties.attribute( "layer" ) );
height = elemDataProperties.attribute( "height" ).toFloat();

QDomElement elemMaterial = elem.firstChildElement( "material" );
material.readXml( elemMaterial );

QDomElement elemShapeProperties = elem.firstChildElement( "shape-properties" );
shapeProperties = QgsXmlUtils::readVariant( elemShapeProperties.firstChildElement() ).toMap();

QDomElement elemTransform = elem.firstChildElement( "transform" );
transform = Utils::stringToMatrix4x4( elemTransform.attribute( "matrix" ) );
}

void PointRenderer::resolveReferences( const QgsProject &project )
{
layerRef.setLayer( project.mapLayer( layerRef.layerId ) );
return mSymbol.get();
}

// ---------------

LineRenderer::LineRenderer()
: altClamping( AltClampRelative )
, altBinding( AltBindCentroid )
, height( 0 )
, extrusionHeight( 0 )
, distance( 1 )
Qt3DCore::QEntity *VectorLayer3DRenderer::createEntity( const Map3D &map ) const
{
QgsVectorLayer *vl = layer();

}
if ( !mSymbol || !vl )
return nullptr;

void LineRenderer::setLayer( QgsVectorLayer *layer )
{
layerRef = QgsMapLayerRef( layer );
if ( mSymbol->type() == "polygon" )
return new PolygonEntity( map, vl, *static_cast<Polygon3DSymbol *>( mSymbol.get() ) );
else if ( mSymbol->type() == "point" )
return new PointEntity( map, vl, *static_cast<Point3DSymbol *>( mSymbol.get() ) );
else if ( mSymbol->type() == "line" )
return new LineEntity( map, vl, *static_cast<Line3DSymbol *>( mSymbol.get() ) );
else
return nullptr;
}

QgsVectorLayer *LineRenderer::layer() const
void VectorLayer3DRenderer::writeXml( QDomElement &elem ) const
{
return qobject_cast<QgsVectorLayer *>( layerRef.layer );
}
QDomDocument doc = elem.ownerDocument();

Abstract3DRenderer *LineRenderer::clone() const
{
return new LineRenderer( *this );
}
elem.setAttribute( "layer", layerRef.layerId );

Qt3DCore::QEntity *LineRenderer::createEntity( const Map3D &map ) const
{
return new LineEntity( map, *this );
QDomElement elemSymbol = doc.createElement( "symbol" );
if ( mSymbol )
{
elemSymbol.setAttribute( "type", mSymbol->type() );
mSymbol->writeXml( elemSymbol );
}
elem.appendChild( elemSymbol );
}

void LineRenderer::writeXml( QDomElement &elem ) const
void VectorLayer3DRenderer::readXml( const QDomElement &elem )
{
QDomDocument doc = elem.ownerDocument();
layerRef = QgsMapLayerRef( elem.attribute( "layer" ) );

QDomElement elemDataProperties = doc.createElement( "data" );
elemDataProperties.setAttribute( "layer", layerRef.layerId );
elemDataProperties.setAttribute( "alt-clamping", Utils::altClampingToString( altClamping ) );
elemDataProperties.setAttribute( "alt-binding", Utils::altBindingToString( altBinding ) );
elemDataProperties.setAttribute( "height", height );
elemDataProperties.setAttribute( "extrusion-height", extrusionHeight );
elemDataProperties.setAttribute( "distance", distance );
elem.appendChild( elemDataProperties );

QDomElement elemMaterial = doc.createElement( "material" );
material.writeXml( elemMaterial );
elem.appendChild( elemMaterial );
}
QDomElement elemSymbol = elem.firstChildElement( "symbol" );
QString symbolType = elemSymbol.attribute( "type" );
Abstract3DSymbol *symbol = nullptr;
if ( symbolType == "polygon" )
symbol = new Polygon3DSymbol;
else if ( symbolType == "point" )
symbol = new Point3DSymbol;
else if ( symbolType == "line" )
symbol = new Line3DSymbol;

void LineRenderer::readXml( const QDomElement &elem )
{
QDomElement elemDataProperties = elem.firstChildElement( "data" );
layerRef = QgsMapLayerRef( elemDataProperties.attribute( "layer" ) );
altClamping = Utils::altClampingFromString( elemDataProperties.attribute( "alt-clamping" ) );
altBinding = Utils::altBindingFromString( elemDataProperties.attribute( "alt-binding" ) );
height = elemDataProperties.attribute( "height" ).toFloat();
extrusionHeight = elemDataProperties.attribute( "extrusion-height" ).toFloat();
distance = elemDataProperties.attribute( "distance" ).toFloat();

QDomElement elemMaterial = elem.firstChildElement( "material" );
material.readXml( elemMaterial );
if ( symbol )
symbol->readXml( elemSymbol );
mSymbol.reset( symbol );
}

void LineRenderer::resolveReferences( const QgsProject &project )
void VectorLayer3DRenderer::resolveReferences( const QgsProject &project )
{
layerRef.setLayer( project.mapLayer( layerRef.layerId ) );
}
79 changes: 15 additions & 64 deletions src/3d/abstract3drenderer.h
Expand Up @@ -12,6 +12,7 @@

class QgsVectorLayer;

class Abstract3DSymbol;
class Map3D;


Expand All @@ -20,7 +21,7 @@ namespace Qt3DCore
class QEntity;
}

class Abstract3DRenderer //: public QObject
class _3D_EXPORT Abstract3DRenderer //: public QObject
{
//Q_OBJECT
public:
Expand All @@ -36,85 +37,35 @@ class Abstract3DRenderer //: public QObject
};


class _3D_EXPORT PolygonRenderer : public Abstract3DRenderer
/** 3D renderer that renders all features of a vector layer with the same 3D symbol.
* The appearance if completely defined by the symbol.
*/
class _3D_EXPORT VectorLayer3DRenderer : public Abstract3DRenderer
{
public:
PolygonRenderer();
//! Takes ownership of the symbol object
explicit VectorLayer3DRenderer( Abstract3DSymbol *s = nullptr );
~VectorLayer3DRenderer();

void setLayer( QgsVectorLayer *layer );
QgsVectorLayer *layer() const;

QString type() const override { return "polygon"; }
Abstract3DRenderer *clone() const override;
Qt3DCore::QEntity *createEntity( const Map3D &map ) const override;

void writeXml( QDomElement &elem ) const override;
void readXml( const QDomElement &elem ) override;
void resolveReferences( const QgsProject &project ) override;

AltitudeClamping altClamping; //! how to handle altitude of vector features
AltitudeBinding altBinding; //! how to handle clamping of vertices of individual features

float height; //!< Base height of polygons
float extrusionHeight; //!< How much to extrude (0 means no walls)
PhongMaterialSettings material; //!< Defines appearance of objects
//! takes ownership of the symbol
void setSymbol( Abstract3DSymbol *symbol );
const Abstract3DSymbol *symbol() const;

private:
QgsMapLayerRef layerRef; //!< Layer used to extract polygons from
};

class _3D_EXPORT PointRenderer : public Abstract3DRenderer
{
public:
PointRenderer();

void setLayer( QgsVectorLayer *layer );
QgsVectorLayer *layer() const;

QString type() const override { return "point"; }
QString type() const override { return "vector"; }
Abstract3DRenderer *clone() const override;
Qt3DCore::QEntity *createEntity( const Map3D &map ) const override;

void writeXml( QDomElement &elem ) const override;
void readXml( const QDomElement &elem ) override;
void resolveReferences( const QgsProject &project ) override;

float height;
PhongMaterialSettings material; //!< Defines appearance of objects
QVariantMap shapeProperties; //!< What kind of shape to use and what
QMatrix4x4 transform; //!< Transform of individual instanced models

private:
QgsMapLayerRef layerRef; //!< Layer used to extract points from
QgsMapLayerRef layerRef; //!< Layer used to extract polygons from
std::unique_ptr<Abstract3DSymbol> mSymbol; //!< 3D symbol that defines appearance
};

class _3D_EXPORT LineRenderer : public Abstract3DRenderer
{
public:
LineRenderer();

void setLayer( QgsVectorLayer *layer );
QgsVectorLayer *layer() const;

QString type() const override { return "line"; }
Abstract3DRenderer *clone() const override;
Qt3DCore::QEntity *createEntity( const Map3D &map ) const override;

void writeXml( QDomElement &elem ) const override;
void readXml( const QDomElement &elem ) override;
void resolveReferences( const QgsProject &project ) override;

AltitudeClamping altClamping; //! how to handle altitude of vector features
AltitudeBinding altBinding; //! how to handle clamping of vertices of individual features

float height; //!< Base height of polygons
float extrusionHeight; //!< How much to extrude (0 means no walls)
PhongMaterialSettings material; //!< Defines appearance of objects

float distance; //!< Distance of buffer of lines

private:
QgsMapLayerRef layerRef; //!< Layer used to extract points from
};

#endif // ABSTRACT3DRENDERER_H

0 comments on commit b9dd6bc

Please sign in to comment.