17#include "moc_qgsvirtualpointcloudentity_p.cpp" 
   18#include "qgsvirtualpointcloudprovider.h" 
   26QgsVirtualPointCloudEntity::QgsVirtualPointCloudEntity(
 
   31  float maximumScreenSpaceError,
 
   32  bool showBoundingBoxes,
 
   37  : Qgs3DMapSceneEntity( map, nullptr )
 
   39  , mCoordinateTransform( coordinateTransform )
 
   40  , mZValueScale( zValueScale )
 
   41  , mZValueOffset( zValueOffset )
 
   42  , mPointBudget( pointBudget )
 
   43  , mMaximumScreenSpaceError( maximumScreenSpaceError )
 
   44  , mShowBoundingBoxes( showBoundingBoxes )
 
   46  mSymbol.reset( symbol );
 
   48  const QVector<QgsPointCloudSubIndex> subIndexes = provider()->subIndexes();
 
   49  for ( 
int i = 0; i < subIndexes.size(); ++i )
 
   51    const QgsPointCloudSubIndex &si = subIndexes.at( i );
 
   54    mBboxes << 
QgsBox3D( intersection, si.zRange().lower(), si.zRange().upper() );
 
   56    createChunkedEntityForSubIndex( i );
 
   59  if ( provider()->overview() )
 
   61    mOverviewEntity = 
new QgsPointCloudLayerChunkedEntity(
 
   64      provider()->overview(),
 
   67      mMaximumScreenSpaceError,
 
   73    mOverviewEntity->setParent( 
this );
 
   74    connect( mOverviewEntity, &QgsChunkedEntity::pendingJobsCountChanged, 
this, &Qgs3DMapSceneEntity::pendingJobsCountChanged );
 
   75    connect( mOverviewEntity, &QgsChunkedEntity::newEntityCreated, 
this, &Qgs3DMapSceneEntity::newEntityCreated );
 
   76    emit newEntityCreated( mOverviewEntity );
 
   82  mBboxesEntity = 
new QgsChunkBoundsEntity( boundsEntityOrigin, 
this );
 
   84  connect( 
this, &QgsVirtualPointCloudEntity::subIndexNeedsLoading, provider(), &QgsVirtualPointCloudProvider::loadSubIndex, Qt::QueuedConnection );
 
   85  connect( provider(), &QgsVirtualPointCloudProvider::subIndexLoaded, 
this, &QgsVirtualPointCloudEntity::createChunkedEntityForSubIndex );
 
   88QList<QgsChunkedEntity *> QgsVirtualPointCloudEntity::chunkedEntities()
 const 
   90  return mChunkedEntitiesMap.values();
 
   93QgsVirtualPointCloudProvider *QgsVirtualPointCloudEntity::provider()
 const 
   95  return qobject_cast<QgsVirtualPointCloudProvider *>( mLayer->dataProvider() );
 
   98void QgsVirtualPointCloudEntity::createChunkedEntityForSubIndex( 
int i )
 
  100  const QVector<QgsPointCloudSubIndex> subIndexes = provider()->subIndexes();
 
  101  const QgsPointCloudSubIndex &si = subIndexes.at( i );
 
  104  if ( !si.index() || mBboxes.at( i ).isEmpty() || !si.index().isValid() )
 
  107  QgsPointCloudLayerChunkedEntity *newChunkedEntity = 
new QgsPointCloudLayerChunkedEntity(
 
  111    mCoordinateTransform,
 
  113    mMaximumScreenSpaceError,
 
  120  mChunkedEntitiesMap.insert( i, newChunkedEntity );
 
  121  newChunkedEntity->setParent( 
this );
 
  122  connect( newChunkedEntity, &QgsChunkedEntity::pendingJobsCountChanged, 
this, &Qgs3DMapSceneEntity::pendingJobsCountChanged );
 
  123  connect( newChunkedEntity, &QgsChunkedEntity::newEntityCreated, 
this, &Qgs3DMapSceneEntity::newEntityCreated );
 
  124  emit newEntityCreated( newChunkedEntity );
 
  127void QgsVirtualPointCloudEntity::handleSceneUpdate( 
const SceneContext &sceneContext )
 
  130  const QVector<QgsPointCloudSubIndex> subIndexes = provider()->subIndexes();
 
  131  for ( 
int i = 0; i < subIndexes.size(); ++i )
 
  133    const QgsBox3D &box3D = mBboxes.at( i );
 
  139    constexpr int SPAN = 256;
 
  140    const float epsilon = 
static_cast<float>( std::min( box3D.
width(), box3D.
height() ) ) / SPAN;
 
  141    const float distance = 
static_cast<float>( box3D.
distanceTo( cameraPosMapCoords ) );
 
  143    constexpr float THRESHOLD = .2;
 
  147    const bool displayAsBbox = sceneContext.cameraPos.isNull() || sse < THRESHOLD;
 
  148    if ( !displayAsBbox && !subIndexes.at( i ).index() )
 
  149      emit subIndexNeedsLoading( i );
 
  151    setRenderSubIndexAsBbox( i, displayAsBbox );
 
  152    if ( !displayAsBbox && mChunkedEntitiesMap.contains( i ) )
 
  153      mChunkedEntitiesMap[i]->handleSceneUpdate( sceneContext );
 
  160    mOverviewEntity->handleSceneUpdate( sceneContext );
 
  164QgsRange<float> QgsVirtualPointCloudEntity::getNearFarPlaneRange( 
const QMatrix4x4 &viewMatrix )
 const 
  169  for ( QgsChunkedEntity *entity : mChunkedEntitiesMap )
 
  171    if ( entity->isEnabled() )
 
  173      const QgsRange<float> range = entity->getNearFarPlaneRange( viewMatrix );
 
  174      ffar = std::max( range.
upper(), ffar );
 
  175      fnear = std::min( range.
lower(), fnear );
 
  180  if ( fnear == 1e9 && ffar == 0 )
 
  182    for ( 
const QgsBox3D &box : mBboxes )
 
  188      fnear = std::min( fnear, bboxfnear );
 
  189      ffar = std::max( ffar, bboxffar );
 
  196int QgsVirtualPointCloudEntity::pendingJobsCount()
 const 
  199  for ( QgsChunkedEntity *entity : mChunkedEntitiesMap )
 
  201    if ( entity->isEnabled() )
 
  202      jobs += entity->pendingJobsCount();
 
  207bool QgsVirtualPointCloudEntity::needsUpdate()
 const 
  209  for ( QgsChunkedEntity *entity : mChunkedEntitiesMap )
 
  211    if ( entity->isEnabled() && entity->needsUpdate() )
 
  217void QgsVirtualPointCloudEntity::updateBboxEntity()
 
  219  QList<QgsBox3D> bboxes;
 
  224    const QVector<QgsPointCloudSubIndex> subIndexes = provider()->subIndexes();
 
  225    for ( 
int i = 0; i < subIndexes.size(); ++i )
 
  227      if ( mChunkedEntitiesMap.contains( i ) && mChunkedEntitiesMap[i]->isEnabled() )
 
  230      if ( mBboxes.at( i ).isEmpty() )
 
  233      bboxes << mBboxes.at( i );
 
  237  mBboxesEntity->setBoxes( bboxes );
 
  240void QgsVirtualPointCloudEntity::setRenderSubIndexAsBbox( 
int i, 
bool asBbox )
 
  242  if ( !mChunkedEntitiesMap.contains( i ) )
 
  245  mChunkedEntitiesMap[i]->setEnabled( !asBbox );
 
@ RenderOverviewAndExtents
Render point cloud extents over overview point cloud.
 
@ RenderOverview
Render overview point cloud when zoomed out.
 
QgsRectangle extent() const
Returns the 3D scene's 2D extent in the 3D scene's CRS.
 
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used in the 3D scene.
 
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
 
static float screenSpaceError(float epsilon, float distance, int screenSize, float fov)
This routine approximately calculates how an error (epsilon) of an object in world coordinates at giv...
 
static QgsRectangle tryReprojectExtent2D(const QgsRectangle &extent, const QgsCoordinateReferenceSystem &crs1, const QgsCoordinateReferenceSystem &crs2, const QgsCoordinateTransformContext &context)
Reprojects extent from crs1 to crs2 coordinate reference system with context context.
 
static void computeBoundingBoxNearFarPlanes(const QgsAABB &bbox, const QMatrix4x4 &viewMatrix, float &fnear, float &ffar)
This routine computes nearPlane farPlane from the closest and farthest corners point of bounding box ...
 
static QgsAABB fromBox3D(const QgsBox3D &box3D, const QgsVector3D &origin)
Constructs bounding box from QgsBox3D by subtracting origin 3D vector.
 
A 3-dimensional box composed of x, y, z coordinates.
 
Q_DECL_DEPRECATED double distanceTo(const QVector3D &point) const
Returns the smallest distance between the box and the point point (returns 0 if the point is inside t...
 
double width() const
Returns the width of the box.
 
double height() const
Returns the height of the box.
 
bool isEmpty() const
Returns true if the box is empty.
 
QgsCoordinateReferenceSystem crs
 
3D renderer that renders all points from a point cloud layer
 
Qgis::PointCloudZoomOutRenderBehavior zoomOutBehavior() const
Returns the renderer behavior when zoomed out.
 
Represents a map layer supporting display of point clouds.
 
A template based class for storing ranges (lower to upper values).
 
T lower() const
Returns the lower bound of the range.
 
T upper() const
Returns the upper bound of the range.
 
A rectangle specified with double values.
 
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
 
Class for storage of 3D vectors similar to QVector3D, with the difference that it uses double precisi...