Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split point cloud index into implementation & wrapper #59939

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

dvdkon
Copy link
Contributor

@dvdkon dvdkon commented Dec 17, 2024

Description

This PR renames QgsPointCloudIndex to QgsAbstractPointCloudIndex and introduces a new class, QgsPointCloudIndex, which serves as a wrapper for a shared_ptr of the abstract index. This mirrors the arrangement used for QgsTiledSceneIndex and codifies good memory management practices (use of smart pointers for a long-lived shared object) while not exposing the std::shared_pointer directly in the API.

Personally, I see the use of a wrapper class as a hack around SIP's lack of support for smart pointers and would much rather see a simple using QgsPointCloudIndex = std::shared_ptr<...>;. That would, however, require much more complex changes, and the imperfect route chosen in this PR allows us to use good memory management practices today, without any long-term debt (in the future it would be simple to switch to using smart pointers directly).

@dvdkon dvdkon marked this pull request as ready for review December 17, 2024 14:09
@github-actions github-actions bot added this to the 3.42.0 milestone Dec 17, 2024
Copy link

github-actions bot commented Dec 17, 2024

🪟 Windows builds

Download Windows builds of this PR for testing.
Debug symbols for this build are available here.
(Built from commit 5903cc9)

🪟 Windows Qt6 builds

Download Windows Qt6 builds of this PR for testing.
(Built from commit fbea1ee)

@dvdkon dvdkon force-pushed the point-cloud-index-refactor-2 branch from 9a58078 to 5903cc9 Compare December 17, 2024 19:54
src/3d/qgspointcloudlayerchunkloader_p.h Show resolved Hide resolved
@@ -127,7 +127,7 @@ class QgsPointCloudLayerChunkedEntity : public QgsChunkedEntity
{
Q_OBJECT
public:
explicit QgsPointCloudLayerChunkedEntity( Qgs3DMapSettings *map, QgsPointCloudIndex *pc, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maxScreenError, bool showBoundingBoxes, double zValueScale, double zValueOffset, int pointBudget );
explicit QgsPointCloudLayerChunkedEntity( Qgs3DMapSettings *map, QgsPointCloudIndex pc, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maxScreenError, bool showBoundingBoxes, double zValueScale, double zValueOffset, int pointBudget );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
explicit QgsPointCloudLayerChunkedEntity( Qgs3DMapSettings *map, QgsPointCloudIndex pc, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maxScreenError, bool showBoundingBoxes, double zValueScale, double zValueOffset, int pointBudget );
explicit QgsPointCloudLayerChunkedEntity( Qgs3DMapSettings *map, const QgsPointCloudIndex &pc, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maxScreenError, bool showBoundingBoxes, double zValueScale, double zValueOffset, int pointBudget );

src/core/pointcloud/qgspointcloudindex.h Outdated Show resolved Hide resolved
src/3d/symbols/qgspointcloud3dsymbol_p.h Outdated Show resolved Hide resolved
bool gpsTimeFlag() const;
QVariantMap extraMetadata() const override;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is more fragile vs the explicit getter -- I'd rather not see us use QVariantMap for purposes like this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nyalldawson the reasoning is that the gpsTimeFlag is something very specific to one particular file format, with quite minor impact, and it does not deserve to be a part of the public API. And it seemed that over time, we may want to pass more format-specific metadata read from the file header - hence introduction of this fairly generic extraMetadata() function. Given that it is not used for any core functionality, it seems okay to use QVariantMap in this case (I also don't like to see QVariantMap in API)

src/core/pointcloud/qgspointclouddataprovider.cpp Outdated Show resolved Hide resolved
src/core/pointcloud/qgspointcloudindex.h Outdated Show resolved Hide resolved
src/core/pointcloud/qgspointclouddataprovider.h Outdated Show resolved Hide resolved
@@ -279,10 +279,10 @@ class CORE_EXPORT QgsPointCloudDataProvider: public QgsDataProvider
QString mSubsetString;

//! Identify in a specific index (used for sub-indexes)
QVector<QVariantMap> identify( QgsPointCloudIndex *index, double maxError, const QgsGeometry &extentGeometry, const QgsDoubleRange &extentZRange, int pointsLimit ) SIP_SKIP ;
QVector<QVariantMap> identify( QgsPointCloudIndex index, double maxError, const QgsGeometry &extentGeometry, const QgsDoubleRange &extentZRange, int pointsLimit ) SIP_SKIP ;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
QVector<QVariantMap> identify( QgsPointCloudIndex index, double maxError, const QgsGeometry &extentGeometry, const QgsDoubleRange &extentZRange, int pointsLimit ) SIP_SKIP ;
QVector<QVariantMap> identify( const QgsPointCloudIndex &index, double maxError, const QgsGeometry &extentGeometry, const QgsDoubleRange &extentZRange, int pointsLimit ) SIP_SKIP ;

elsewhere too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comments, I'll look through them tomorrow. But I don't think QgsPointCloudIndex should be passed by reference. The point of the class is that it's basically an std::shared_ptr. Passing it by reference might remove a refcount increment at the cost of more indirection, but I'd rather just pass it by value for simplicity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we had the full range of C++ to play with, I'd personally either use std::shared_ptr<QgsAbstractPointCloudIndex> or QgsAbstractPointCloudIndex &, but as-is I'd just use the wrapper everywhere.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm -- I would still push towards references, in all cases EXCEPT those where we know that we're explicitly storing the result in a member variable (and could possibly benefit from a move).

(In general we try to follow Qt's approach for things like this, and they always pass QString by reference, even though it's implicitly shared and copies are cheap.)

@nyalldawson
Copy link
Collaborator

Looking good, thank you! Can you also add some python based tests just to ensure that the bindings are working correctly?

@dvdkon dvdkon force-pushed the point-cloud-index-refactor-2 branch from 0b30cf2 to 167bb26 Compare December 20, 2024 12:06
@dvdkon
Copy link
Contributor Author

dvdkon commented Dec 20, 2024

Looking good, thank you! Can you also add some python based tests just to ensure that the bindings are working correctly?

Thanks! I've exposed the index() method on the data provider as well and added a simple Python test accessing the index.

I've had some trouble getting the SIP bindings to build after this one change, hopefully it passes CI.

@dvdkon dvdkon force-pushed the point-cloud-index-refactor-2 branch from 167bb26 to fbea1ee Compare December 20, 2024 12:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants