Skip to content
Permalink
Browse files

Merge pull request #33480 from wonder-sk/3d-layers-load-in-background

[3d] Load 3D vector layer data in background + tiling
  • Loading branch information
wonder-sk committed Jan 16, 2020
2 parents f39d53b + ee92e10 commit a5c9b3995568edf5d017e85e6b74574328ea5de2
Showing with 1,648 additions and 236 deletions.
  1. +2 −2 external/poly2tri/common/shapes.h
  2. +1 −0 python/3d/3d_auto.sip
  3. +122 −0 python/3d/auto_generated/qgsabstractvectorlayer3drenderer.sip.in
  4. +1 −12 python/3d/auto_generated/qgsrulebased3drenderer.sip.in
  5. +1 −12 python/3d/auto_generated/qgsvectorlayer3drenderer.sip.in
  6. +14 −0 python/core/auto_generated/qgstessellator.sip.in
  7. +6 −0 src/3d/CMakeLists.txt
  8. +80 −2 src/3d/chunks/qgschunkedentity_p.cpp
  9. +31 −1 src/3d/chunks/qgschunkedentity_p.h
  10. +1 −1 src/3d/chunks/qgschunknode_p.h
  11. +5 −2 src/3d/chunks/qgschunkqueuejob_p.h
  12. +59 −63 src/3d/qgs3dmapscene.cpp
  13. +17 −1 src/3d/qgs3dmapscene.h
  14. +85 −0 src/3d/qgs3dutils.cpp
  15. +33 −0 src/3d/qgs3dutils.h
  16. +81 −0 src/3d/qgsabstractvectorlayer3drenderer.cpp
  17. +107 −0 src/3d/qgsabstractvectorlayer3drenderer.h
  18. +11 −0 src/3d/qgsfeature3dhandler_p.cpp
  19. +20 −0 src/3d/qgsfeature3dhandler_p.h
  20. +8 −50 src/3d/qgsrulebased3drenderer.cpp
  21. +2 −9 src/3d/qgsrulebased3drenderer.h
  22. +184 −0 src/3d/qgsrulebasedchunkloader_p.cpp
  23. +118 −0 src/3d/qgsrulebasedchunkloader_p.h
  24. +13 −3 src/3d/qgstessellatedpolygongeometry.cpp
  25. +11 −1 src/3d/qgstessellatedpolygongeometry.h
  26. +10 −29 src/3d/qgsvectorlayer3drenderer.cpp
  27. +2 −9 src/3d/qgsvectorlayer3drenderer.h
  28. +178 −0 src/3d/qgsvectorlayerchunkloader_p.cpp
  29. +117 −0 src/3d/qgsvectorlayerchunkloader_p.h
  30. +38 −12 src/3d/symbols/qgsline3dsymbol_p.cpp
  31. +24 −0 src/3d/symbols/qgspoint3dsymbol_p.cpp
  32. +28 −15 src/3d/symbols/qgspolygon3dsymbol_p.cpp
  33. +5 −0 src/app/3d/qgs3dmapcanvas.cpp
  34. +4 −4 src/app/3d/qgs3dmapcanvasdockwidget.cpp
  35. +1 −1 src/app/3d/qgs3dmapcanvasdockwidget.h
  36. +43 −0 src/app/3d/qgsvectorlayer3dpropertieswidget.cpp
  37. +42 −0 src/app/3d/qgsvectorlayer3dpropertieswidget.h
  38. +12 −1 src/app/3d/qgsvectorlayer3drendererwidget.cpp
  39. +2 −0 src/app/3d/qgsvectorlayer3drendererwidget.h
  40. +1 −0 src/app/CMakeLists.txt
  41. +22 −1 src/core/qgstessellator.cpp
  42. +15 −0 src/core/qgstessellator.h
  43. +69 −0 src/ui/3d/qgsvectorlayer3dpropertieswidget.ui
  44. +11 −5 tests/src/3d/testqgs3drendering.cpp
  45. +11 −0 tests/src/3d/testqgstessellator.cpp
@@ -132,11 +132,11 @@ struct Edge {
if (p1.y > p2.y) {
q = &p1;
p = &p2;
} else if (std::abs(p1.y - p2.y) < 1e-10) {
} else if (p1.y == p2.y) {
if (p1.x > p2.x) {
q = &p1;
p = &p2;
} else if (std::abs(p1.x - p2.x) < 1e-10) {
} else if (p1.x == p2.x) {
// Repeat points
throw std::runtime_error("Edge::Edge: p1 == p2");
}
@@ -1,5 +1,6 @@
// Include auto-generated SIP files
%Include auto_generated/qgs3dtypes.sip
%Include auto_generated/qgsabstractvectorlayer3drenderer.sip
%Include auto_generated/qgsphongmaterialsettings.sip
%Include auto_generated/qgsrulebased3drenderer.sip
%Include auto_generated/qgsvectorlayer3drenderer.sip
@@ -0,0 +1,122 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/3d/qgsabstractvectorlayer3drenderer.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsVectorLayer3DTilingSettings
{
%Docstring
This class defines configuration of how a vector layer gets tiled for 3D rendering.

Zoom levels count tells how deep will be the quadtree and thus how many tiles will
be generated ( 4 ^ (count-1) ). So for example, for count=1 there will be just
a single tile for the whole layer, for count=3 there will be 16 tiles.

.. versionadded:: 3.12
%End

%TypeHeaderCode
#include "qgsabstractvectorlayer3drenderer.h"
%End
public:

int zoomLevelsCount() const;
%Docstring
Returns number of zoom levels. One zoom level means there will be one tile.
Every extra zoom level multiplies number of tiles by four. For example, three
zoom levels will produce 16 tiles at the highest zoom level. It is therefore
recommended to keep the number of zoom levels low to prevent excessive number
of tiles.
%End

void setZoomLevelsCount( int count );
%Docstring
Sets number of zoom levels. See zoomLevelsCount() documentation for more details.
%End

void setShowBoundingBoxes( bool enabled );
%Docstring
Sets whether to display bounding boxes of entity's tiles (for debugging)
%End
bool showBoundingBoxes() const;
%Docstring
Returns whether to display bounding boxes of entity's tiles (for debugging)
%End

void writeXml( QDomElement &elem ) const;
%Docstring
Writes content of the object to XML
%End
void readXml( const QDomElement &elem );
%Docstring
Reads content of the object from XML
%End

};


class QgsAbstractVectorLayer3DRenderer : QgsAbstract3DRenderer /Abstract/
{
%Docstring
Base class for 3D renderers that are based on vector layers.

.. versionadded:: 3.12
%End

%TypeHeaderCode
#include "qgsabstractvectorlayer3drenderer.h"
%End
public:
QgsAbstractVectorLayer3DRenderer();

void setLayer( QgsVectorLayer *layer );
%Docstring
Sets vector layer associated with the renderer
%End
QgsVectorLayer *layer() const;
%Docstring
Returns vector layer associated with the renderer
%End

void setTilingSettings( const QgsVectorLayer3DTilingSettings &settings );
%Docstring
Sets tiling settings of the renderer
%End
QgsVectorLayer3DTilingSettings tilingSettings() const;
%Docstring
Returns tiling settings of the renderer
%End

virtual void resolveReferences( const QgsProject &project );


protected:
void copyBaseProperties( QgsAbstractVectorLayer3DRenderer *r ) const;
%Docstring
Copies common properties of this object to another object
%End
void writeXmlBaseProperties( QDomElement &elem, const QgsReadWriteContext &context ) const;
%Docstring
Writes common properties of this object to DOM element
%End
void readXmlBaseProperties( const QDomElement &elem, const QgsReadWriteContext &context );
%Docstring
Reads common properties of this object from DOM element
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/3d/qgsabstractvectorlayer3drenderer.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -39,7 +39,7 @@ Creates an instance of a 3D renderer based on a DOM element with renderer config
};


class QgsRuleBased3DRenderer : QgsAbstract3DRenderer
class QgsRuleBased3DRenderer : QgsAbstractVectorLayer3DRenderer
{
%Docstring
Rule-based 3D renderer.
@@ -244,15 +244,6 @@ Construct renderer with the given root rule (takes ownership)
%End
~QgsRuleBased3DRenderer();

void setLayer( QgsVectorLayer *layer );
%Docstring
Sets vector layer associated with the renderer
%End
QgsVectorLayer *layer() const;
%Docstring
Returns vector layer associated with the renderer
%End

QgsRuleBased3DRenderer::Rule *rootRule();
%Docstring
Returns pointer to the root rule
@@ -266,8 +257,6 @@ Returns pointer to the root rule

virtual void readXml( const QDomElement &elem, const QgsReadWriteContext &context );

virtual void resolveReferences( const QgsProject &project );


};

@@ -41,7 +41,7 @@ Creates an instance of a 3D renderer based on a DOM element with renderer config
};


class QgsVectorLayer3DRenderer : QgsAbstract3DRenderer
class QgsVectorLayer3DRenderer : QgsAbstractVectorLayer3DRenderer
{
%Docstring
3D renderer that renders all features of a vector layer with the same 3D symbol.
@@ -57,15 +57,6 @@ The appearance is completely defined by the symbol.
explicit QgsVectorLayer3DRenderer( QgsAbstract3DSymbol *s /Transfer/ = 0 );
%Docstring
Takes ownership of the symbol object
%End

void setLayer( QgsVectorLayer *layer );
%Docstring
Sets vector layer associated with the renderer
%End
QgsVectorLayer *layer() const;
%Docstring
Returns vector layer associated with the renderer
%End

void setSymbol( QgsAbstract3DSymbol *symbol /Transfer/ );
@@ -85,8 +76,6 @@ Returns 3D symbol associated with the renderer

virtual void readXml( const QDomElement &elem, const QgsReadWriteContext &context );

virtual void resolveReferences( const QgsProject &project );


private:
QgsVectorLayer3DRenderer( const QgsVectorLayer3DRenderer & );
@@ -66,6 +66,20 @@ Returns size of one vertex entry in bytes
%End


float zMinimum() const;
%Docstring
Returns minimal Z value of the data (in world coordinates)

.. versionadded:: 3.12
%End

float zMaximum() const;
%Docstring
Returns maximal Z value of the data (in world coordinates)

.. versionadded:: 3.12
%End

};

/************************************************************************
@@ -4,6 +4,7 @@
SET(QGIS_3D_SRCS
qgsaabb.cpp
qgsabstract3dengine.cpp
qgsabstractvectorlayer3drenderer.cpp
qgs3danimationsettings.cpp
qgs3dmapscene.cpp
qgs3dmapsettings.cpp
@@ -17,9 +18,11 @@ SET(QGIS_3D_SRCS
qgspointlightsettings.cpp
qgsraycastingutils_p.cpp
qgsrulebased3drenderer.cpp
qgsrulebasedchunkloader_p.cpp
qgstessellatedpolygongeometry.cpp
qgstilingscheme.cpp
qgsvectorlayer3drenderer.cpp
qgsvectorlayerchunkloader_p.cpp
qgsmeshlayer3drenderer.cpp
qgswindow3dengine.cpp

@@ -70,6 +73,7 @@ SET(QGIS_3D_HDRS
qgs3dutils.h
qgsaabb.h
qgsabstract3dengine.h
qgsabstractvectorlayer3drenderer.h
qgscameracontroller.h
qgscamerapose.h
qgslayoutitem3dmap.h
@@ -100,6 +104,8 @@ SET(QGIS_3D_HDRS
)

SET(QGIS_3D_PRIVATE_HDRS
qgsrulebasedchunkloader_p.h
qgsvectorlayerchunkloader_p.h
chunks/qgschunkboundsentity_p.h
chunks/qgschunkedentity_p.h
chunks/qgschunklist_p.h
@@ -17,12 +17,15 @@

#include <QElapsedTimer>
#include <QVector4D>
#include <Qt3DRender/QObjectPicker>
#include <Qt3DRender/QPickTriangleEvent>

#include "qgs3dutils.h"
#include "qgschunkboundsentity_p.h"
#include "qgschunklist_p.h"
#include "qgschunkloader_p.h"
#include "qgschunknode_p.h"
#include "qgstessellatedpolygongeometry.h"

#include "qgseventtracing.h"

@@ -244,9 +247,9 @@ void QgsChunkedEntity::update( QgsChunkNode *node, const SceneState &state )
return;
}

//qDebug() << node->x << "|" << node->y << "|" << node->z << " " << tau << " " << screenSpaceError(node, state);
//qDebug() << node->tileX() << "|" << node->tileY() << "|" << node->tileZ() << " " << mTau << " " << screenSpaceError(node, state);

if ( screenSpaceError( node, state ) <= mTau )
if ( mTau > 0 && screenSpaceError( node, state ) <= mTau )
{
// acceptable error for the current chunk - let's render it

@@ -343,6 +346,15 @@ void QgsChunkedEntity::onActiveJobFinished()
node->setLoaded( entity );

mReplacementQueue->insertFirst( node->replacementQueueEntry() );

if ( mPickingEnabled )
{
Qt3DRender::QObjectPicker *picker = new Qt3DRender::QObjectPicker( node->entity() );
node->entity()->addComponent( picker );
connect( picker, &Qt3DRender::QObjectPicker::clicked, this, &QgsChunkedEntity::onPickEvent );
}

emit newEntityCreated( entity );
}
else
{
@@ -450,4 +462,70 @@ void QgsChunkedEntity::cancelActiveJobs()
}
}


void QgsChunkedEntity::setPickingEnabled( bool enabled )
{
if ( mPickingEnabled == enabled )
return;

mPickingEnabled = enabled;

if ( enabled )
{
QgsChunkListEntry *entry = mReplacementQueue->first();
while ( entry )
{
QgsChunkNode *node = entry->chunk;
Qt3DRender::QObjectPicker *picker = new Qt3DRender::QObjectPicker( node->entity() );
node->entity()->addComponent( picker );
connect( picker, &Qt3DRender::QObjectPicker::clicked, this, &QgsChunkedEntity::onPickEvent );

entry = entry->next;
}
}
else
{
for ( Qt3DRender::QObjectPicker *picker : findChildren<Qt3DRender::QObjectPicker *>() )
picker->deleteLater();
}
}

void QgsChunkedEntity::onPickEvent( Qt3DRender::QPickEvent *event )
{
Qt3DRender::QPickTriangleEvent *triangleEvent = qobject_cast<Qt3DRender::QPickTriangleEvent *>( event );
if ( !triangleEvent )
return;

Qt3DRender::QObjectPicker *picker = qobject_cast<Qt3DRender::QObjectPicker *>( sender() );
if ( !picker )
return;

Qt3DCore::QEntity *entity = qobject_cast<Qt3DCore::QEntity *>( picker->parent() );
if ( !entity )
return;

// go figure out feature ID from the triangle index
QgsFeatureId fid = FID_NULL;
for ( Qt3DRender::QGeometryRenderer *geomRenderer : entity->findChildren<Qt3DRender::QGeometryRenderer *>() )
{
// unfortunately we can't access which sub-entity triggered the pick event
// so as a temporary workaround let's just ignore the entity with selection
// and hope the event was the main entity (QTBUG-58206)
if ( geomRenderer->objectName() != QLatin1String( "main" ) )
continue;

if ( QgsTessellatedPolygonGeometry *g = qobject_cast<QgsTessellatedPolygonGeometry *>( geomRenderer->geometry() ) )
{
fid = g->triangleIndexToFeatureId( triangleEvent->triangleIndex() );
if ( !FID_IS_NULL( fid ) )
break;
}
}

if ( !FID_IS_NULL( fid ) )
{
emit pickedObject( event, fid );
}
}

/// @endcond

0 comments on commit a5c9b39

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