| RDB 2

queryUpdate.hpp
Go to the documentation of this file.
1 /*
2 *******************************************************************************
3 *
4 * Copyright 2025 RIEGL Laser Measurement Systems
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * SPDX-License-Identifier: Apache-2.0
19 *
20 *******************************************************************************
21 */
22 /*!
23 *******************************************************************************
24 *
25 * \file queryUpdate.hpp
26 * \author RIEGL LMS GmbH, Austria
27 * \brief Point update query
28 * \version 2015-10-14/AW: Initial version
29 * \version 2017-11-24/AW: Constructors declared as "explicit" (#2825)
30 * \version 2018-07-05/AW: Wrapper function bindBuffer() added
31 * \version 2020-01-17/AW: Wrapper function bindMember() added (#3497)
32 *
33 *******************************************************************************
34 */
35
36 #ifndef RIEGL_RDB_POINTCLOUD_QUERYUPDATE_HPP
37 #define RIEGL_RDB_POINTCLOUD_QUERYUPDATE_HPP
38
39 //---< INCLUDES >---------------------------------------------------------------
40
41 #include <memory>
42 #include <string>
43 #include <cstdlib>
44 #include <cstdint>
45
46 #include "riegl/rdb/pointcloud/dataTypes.hpp"
47 #include "riegl/rdb/pointcloud/pointcloudData.hpp"
48
49 //---< NAMESPACE >--------------------------------------------------------------
50
51 namespace riegl {
52 namespace rdb {
53 namespace pointcloud {
54
55 //---< CLASS QueryUpdate >------------------------------------------------------
56 /*!
57 * \brief Point update query
58 *
59 * This class can be used to update (modify) attributes of existing points.
60 *
61 * \see riegl::rdb::Pointcloud::update()
62 *
63 * \note You either must delete the query object or call close()
64 * __before__ the parent Pointcloud instance is closed/deleted!
65 */
66 class QueryUpdate
67 {
68 public:
69 /*!
70 * \brief Default constructor
71 *
72 * Creates a null query - i.e. the query cannot be used to update points.
73 *
74 * \see riegl::rdb::Pointcloud::update()
75 */
76 explicit QueryUpdate();
77
78 /*!
79 * \brief Constructor
80 *
81 * Creates a query prepared for updating points.
82 *
83 * \note You cannot create new QueryUpdate objects this way,
84 * use riegl::rdb::Pointcloud::update() instead.
85 */
86 explicit QueryUpdate(riegl::rdb::PointcloudData *pointcloud);
87
88 /*!
89 * \brief Check if query is not null
90 *
91 * \see valid()
92 */
93 operator bool() const;
94
95 /*!
96 * \brief Check if query is not null
97 *
98 * A null query cannot be used to update points.
99 */
100 bool valid() const;
101
102 /*!
103 * \brief Finish query
104 *
105 * Call this function when done with updating points.
106 */
107 void close();
108
109 /*!
110 * \brief Bind attribute buffer
111 *
112 * Use this function to define a source buffer for a point attribute.
113 * Exactly one buffer can be defined for an attribute (i.e. only the
114 * most recently defined buffer will be used).
115 *
116 * You can but don't need to define a buffer for each attribute. If
117 * no buffer is defined for an attribute, it remains unchanged.
118 *
119 * The buffer is expected to be n*s*d bytes large, where
120 * __n__ is the number of points defined in next(),
121 * __s__ is the size of one element as defined by 'dataType' and
122 * __d__ is the number of attribute dimensions (elements).
123 *
124 * \note This function just stores the buffer pointer - it does
125 * __NOT__ copy the data contained in the buffer. So make
126 * sure that the buffer remains valid until you call next().
127 *
128 * \note This function expects a buffer for the point ID attribute.
129 *
130 * \see riegl::rdb::pointcloud::PointAttributes
131 */
132 void bind(
133 const std::string &attribute, //!< [in] attribute name
134 const DataType dataType, //!< [in] buffer data type
135 const void *buffer, //!< [in] buffer location
136 const std::int32_t stride = 0 //!< [in] bytes between beginnings of successive elements (0: auto)
137 );
138
139 //! \copydoc bind()
140 template <typename ValueType>
141 void bindBuffer(
142 const std::string &attribute, //!< [in] attribute name
143 const ValueType &buffer, //!< [in] buffer (data, pointer to data, std::array or std::vector)
144 const std::int32_t stride = 0 //!< [in] bytes between beginnings of successive elements (0: auto)
145 )
146 {
147 bind(attribute, dataTypeOf(buffer), dataPointerOf(buffer), stride);
148 }
149
150 /*!
151 * \brief Bind attribute buffer
152 *
153 * This is a variant of bindBuffer() that allows to bind a member variable
154 * of an object as attribute buffer. The object can be part of a container
155 * that stores the objects contiguously (e.g. std::vector, std::array) and
156 * the stride is automatically derived from the object size.
157 *
158 * \see bindBuffer()
159 */
160 template <typename ObjectType, typename MemberPointer>
161 void bindMember(
162 const std::string &attribute, //!< [in] attribute name
163 const ObjectType &object, //!< [in] e.g. first object of container
164 const MemberPointer member //!< [in] object member variable pointer
165 )
166 {
167 bindBuffer(
168 attribute, object.*member,
169 static_cast<std::int32_t>(sizeof(ObjectType))
170 );
171 }
172
173 //! \copydoc bindMember()
174 template <typename ObjectType, typename MemberPointer>
175 void bindMember(
176 const std::string &attribute, //!< [in] attribute name
177 const ObjectType &object, //!< [in] e.g. first object of container
178 const MemberPointer member, //!< [in] object member variable pointer
179 const std::size_t index //!< [in] index for array-like object members
180 )
181 {
182 bindBuffer(
183 attribute, (object.*member)[index],
184 static_cast<std::int32_t>(sizeof(ObjectType))
185 );
186 }
187
188 /*!
189 * \brief Update points
190 *
191 * Use this function to actually read the point attributes from
192 * all defined buffers and update the points in the database.
193 *
194 * Afterwards you may re-fill the buffers or define new buffers
195 * with bind() and call next() again until all points have been
196 * updated.
197 *
198 * \remark It is assumed that the points are given in the exact same order as
199 * returned by the select query (riegl::rdb::pointcloud::QuerySelect).
200 * If the points are given in a different order, the update will still
201 * work but may take more time to finish. Of course it is not required
202 * to update all points (you don't need to provide points that you do
203 * not want to update).
204 *
205 * \note IEEE-754 "NaN" values contained in floating point source
206 * buffers are ignored and the attribute's default value is
207 * used instead. Furthermore IEEE-754 "Infinity" values will
208 * always cause next() to fail with error code 10414, i.e.
209 * riegl::rdb::Error::QueryAttributeValueOutOfRange.
210 *
211 * \note Since version 2.4.2, unit vector point attributes (e.g.
212 * "riegl.direction") are automatically normalized (divided
213 * by the vector length) on insertion. This is done for all
214 * point attributes that meet the following requirements:
215 * `length` is 3, `minimumValue` is -1, `maximumValue` is 1,
216 * `resolution` is not 1, `scaleFactor` is 1, `unitSymbol` is
217 * empty, `invalidValue` is undefined and `tags` contains the
218 * "direction" tag but not the "do-not-normalize" tag.
219 *
220 * \warning If you want to modify the primary point attribute (usually
221 * the point coordinates), you __must__ either read __all__ points
222 * with a select query (class QuerySelect) first and update them
223 * later, or use two different instances of riegl::rdb::Pointcloud
224 * on the same database and use one instance to read (select) and
225 * the other instance to write (update) the points. In other words:
226 * It is not allowed to alternately call next() on an instance of
227 * QuerySelect and an instance of QueryUpdate if both were started
228 * on the same Pointcloud instance and the goal is to modify the
229 * primary point attribute.
230 *
231 * \returns the number of points updated
232 */
233 std::uint32_t next(
234 std::uint32_t count //!< [in] size of source buffers in terms of points
235 );
236
237 private:
238 struct Private;
239 std::shared_ptr<Private> data;
240 };
241
242 }}} // namespace riegl::rdb::pointcloud
243
244 #endif // RIEGL_RDB_POINTCLOUD_QUERYUPDATE_HPP
riegl::rdb::pointcloud::DataType
DataType
Point attribute access data type.
Definition: dataTypes.hpp:56
riegl::rdb::pointcloud::dataPointerOf
ValueType * dataPointerOf(ValueType *const value)
Get pointer to variable or to data in a std::array or vector container.
Definition: dataTypes.hpp:176
riegl
RIEGL Laser Measurement Systems GmbH, Austria.
Definition: context.hpp:48
riegl::rdb::pointcloud::dataTypeOf
DataType dataTypeOf()
Convenience wrapper for DataTypeOf class.
Definition: dataTypes.hpp:147
riegl::rdb::pointcloud::QueryUpdate::QueryUpdate
QueryUpdate()
Default constructor.
riegl::rdb::pointcloud::QueryUpdate::next
std::uint32_t next(std::uint32_t count)
Update points.
riegl::rdb::pointcloud::QueryUpdate::bindBuffer
void bindBuffer(const std::string &attribute, const ValueType &buffer, const std::int32_t stride=0)
Bind attribute buffer.
Definition: queryUpdate.hpp:141
riegl::rdb::pointcloud::QueryUpdate
Point update query.
Definition: queryUpdate.hpp:66
riegl::rdb::pointcloud::QueryUpdate::bindMember
void bindMember(const std::string &attribute, const ObjectType &object, const MemberPointer member, const std::size_t index)
Bind attribute buffer.
Definition: queryUpdate.hpp:175
dataTypes.hpp
Point attribute access data types.
riegl::rdb::pointcloud::QueryUpdate::bindMember
void bindMember(const std::string &attribute, const ObjectType &object, const MemberPointer member)
Bind attribute buffer.
Definition: queryUpdate.hpp:161
pointcloudData.hpp
Pointcloud class implementation details.
riegl::rdb::pointcloud::QueryUpdate::valid
bool valid() const
Check if query is not null.
riegl::rdb::pointcloud::QueryUpdate::bind
void bind(const std::string &attribute, const DataType dataType, const void *buffer, const std::int32_t stride=0)
Bind attribute buffer.
riegl::rdb::pointcloud::QueryUpdate::close
void close()
Finish query.