QGIS API Documentation 3.43.0-Master (ebb4087afc0)
Loading...
Searching...
No Matches
qgspointcloudlayerundocommand.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspointcloudlayerundocommand.cpp
3 ---------------------
4 begin : January 2025
5 copyright : (C) 2025 by Stefanos Natsis
6 email : uclaros at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
19#include "qgspointcloudlayer.h"
21
22
26
29 , mNode( n )
30 , mAttribute( attribute )
31 , mNewValue( value )
32{
34 QgsPointCloudEditingIndex *editIndex = static_cast<QgsPointCloudEditingIndex *>( index.get() );
35
36 if ( editIndex->mEditedNodeData.contains( n ) )
37 {
38 const QgsPointCloudAttributeCollection allAttributes = index.attributes();
40 req.setAttributes( allAttributes );
41 // we want to iterate all points so we have the correct point indexes within the node
43 std::unique_ptr<QgsPointCloudBlock> block = index.nodeData( n, req );
44 const char *ptr = block->data();
45 block->attributes().find( attribute.name(), mAttributeOffset );
46 const int size = block->pointRecordSize();
47 for ( const int point : points )
48 {
49 const int offset = point * size + mAttributeOffset;
50 const double oldValue = attribute.convertValueToDouble( ptr + offset );
51 mPointValues[point] = oldValue;
52 }
53 }
54 else
55 {
56 // If this is the first time this node is edited, we don't need the previous values, we will just discard the node from the edit index when undoing
57 // we still need the keys in mPointValues though as they are the points to be modified in the Redo stage, so we populate them with some NaNs
58 mFirstEditForNode = true;
59 for ( const int point : points )
60 {
61 mPointValues[point] = std::numeric_limits<double>::quiet_NaN();
62 }
63 }
64}
65
67{
68 undoRedoPrivate( true );
69}
70
72{
73 undoRedoPrivate( false );
74}
75
76void QgsPointCloudLayerUndoCommandChangeAttribute::undoRedoPrivate( bool isUndo )
77{
78 QgsPointCloudEditingIndex *editIndex = static_cast<QgsPointCloudEditingIndex *>( mLayer->index().get() );
79 QgsCopcPointCloudIndex *copcIndex = static_cast<QgsCopcPointCloudIndex *>( editIndex->mIndex.get() );
80
81 QByteArray chunkData;
82 if ( editIndex->mEditedNodeData.contains( mNode ) )
83 {
84 chunkData = editIndex->mEditedNodeData[mNode];
85 }
86 else
87 {
88 QPair<uint64_t, int32_t> offsetSizePair = copcIndex->mHierarchyNodePos[mNode];
89 chunkData = copcIndex->readRange( offsetSizePair.first, offsetSizePair.second );
90 }
91
92 QByteArray data;
93 if ( isUndo && mFirstEditForNode )
94 {
95 editIndex->mEditedNodeData.remove( mNode );
96 }
97 else if ( isUndo )
98 {
99 data = QgsPointCloudLayerEditUtils::updateChunkValues( copcIndex, chunkData, mAttribute, mNode, mPointValues );
100 mLayer->index().updateNodeData( {{mNode, data}} );
101 }
102 else
103 {
104 data = QgsPointCloudLayerEditUtils::updateChunkValues( copcIndex, chunkData, mAttribute, mNode, mPointValues, mNewValue );
105 mLayer->index().updateNodeData( {{mNode, data}} );
106 }
107
108 emit mLayer->chunkAttributeValuesChanged( mNode );
109}
Collection of point cloud attributes.
Attribute for point cloud data pair of name and size in bytes.
QString name() const
Returns name of the attribute.
double convertValueToDouble(const char *ptr) const
Returns the attribute's value as a double for data pointed to by ptr.
The QgsPointCloudEditingIndex class is a QgsPointCloudIndex that is used as an editing buffer when ed...
Smart pointer for QgsAbstractPointCloudIndex.
std::unique_ptr< QgsPointCloudBlock > nodeData(const QgsPointCloudNodeId &n, const QgsPointCloudRequest &request)
Returns node data block.
bool updateNodeData(const QHash< QgsPointCloudNodeId, QByteArray > &data)
Tries to update the data for the specified nodes.
QgsAbstractPointCloudIndex * get()
Returns pointer to the implementation class.
QgsPointCloudAttributeCollection attributes() const
Returns all attributes that are stored in the file.
static QByteArray updateChunkValues(QgsCopcPointCloudIndex *copcIndex, const QByteArray &chunkData, const QgsPointCloudAttribute &attribute, const QgsPointCloudNodeId &n, const QHash< int, double > &pointValues, std::optional< double > newValue=std::nullopt)
Sets new classification value for the given points in voxel and return updated chunk data.
QgsPointCloudLayerUndoCommandChangeAttribute(QgsPointCloudLayer *layer, const QgsPointCloudNodeId &n, const QVector< int > &points, const QgsPointCloudAttribute &attribute, double value)
Constructor for QgsPointCloudLayerUndoCommandChangeAttribute.
Base class for undo/redo command for point cloud editing.
QgsPointCloudLayerUndoCommand(QgsPointCloudLayer *layer)
Ctor.
Represents a map layer supporting display of point clouds.
QgsPointCloudIndex index() const
Returns the point cloud index associated with the layer.
void chunkAttributeValuesChanged(const QgsPointCloudNodeId &n)
Emitted when a node gets some attribute values of some points changed.
Represents a indexed point cloud node's position in octree.
Point cloud data request.
void setIgnoreIndexFilterEnabled(bool enable)
When enable is true, the request will ignore the point cloud index's filter expression and use an emp...
void setAttributes(const QgsPointCloudAttributeCollection &attributes)
Set attributes filter in the request.