RDB 2
queryUpdate.hpp
Go to the documentation of this file.
1 /*
2  *******************************************************************************
3  *
4  * Copyright 2021 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 <cstdint>
46 
47 //---< NAMESPACE >--------------------------------------------------------------
48 
49 namespace riegl {
50 namespace rdb {
51 namespace pointcloud {
52 
53 //---< CLASS QueryUpdate >------------------------------------------------------
54 /*!
55  * \brief Point update query
56  *
57  * This class can be used to update (modify) attributes of existing points.
58  *
59  * \see riegl::rdb::Pointcloud::update()
60  *
61  * \note You either must delete the query object or call close()
62  * __before__ the parent Pointcloud instance is closed/deleted!
63  */
65 {
66 public:
67  /*!
68  * \brief Default constructor
69  *
70  * Creates a null query - i.e. the query cannot be used to update points.
71  *
72  * \see riegl::rdb::Pointcloud::update()
73  */
74  explicit QueryUpdate();
75 
76  /*!
77  * \brief Constructor
78  *
79  * Creates a query prepared for updating points.
80  *
81  * \note You cannot create new QueryUpdate objects this way,
82  * use riegl::rdb::Pointcloud::update() instead.
83  */
84  explicit QueryUpdate(riegl::rdb::PointcloudData *pointcloud);
85 
86  /*!
87  * \brief Check if query is not null
88  *
89  * \see valid()
90  */
91  operator bool() const;
92 
93  /*!
94  * \brief Check if query is not null
95  *
96  * A null query cannot be used to update points.
97  */
98  bool valid() const;
99 
100  /*!
101  * \brief Finish query
102  *
103  * Call this function when done with updating points.
104  */
105  void close();
106 
107  /*!
108  * \brief Bind attribute buffer
109  *
110  * Use this function to define a source buffer for a point attribute.
111  * Exactly one buffer can be defined for an attribute (i.e. only the
112  * most recently defined buffer will be used).
113  *
114  * You can but don't need to define a buffer for each attribute. If
115  * no buffer is defined for an attribute, it remains unchanged.
116  *
117  * The buffer is expected to be n*s*d bytes large, where
118  * __n__ is the number of points defined in next(),
119  * __s__ is the size of one element as defined by 'dataType' and
120  * __d__ is the number of attribute dimensions (elements).
121  *
122  * \note This function just stores the buffer pointer - it does
123  * __NOT__ copy the data contained in the buffer. So make
124  * sure that the buffer remains valid until you call next().
125  *
126  * \note This function expects a buffer for the point ID attribute.
127  *
128  * \see riegl::rdb::pointcloud::PointAttributes
129  */
130  void bind(
131  const std::string &attribute, //!< [in] attribute name
132  const DataType dataType, //!< [in] buffer data type
133  const void *buffer, //!< [in] buffer location
134  const int32_t stride = 0 //!< [in] bytes between beginnings of successive elements (0: auto)
135  );
136 
137  //! \copydoc bind()
138  template <typename ValueType>
140  const std::string &attribute, //!< [in] attribute name
141  const ValueType &buffer, //!< [in] buffer (data, pointer to data, std::array or std::vector)
142  const int32_t stride = 0 //!< [in] bytes between beginnings of successive elements (0: auto)
143  )
144  {
145  bind(attribute, dataTypeOf(buffer), dataPointerOf(buffer), stride);
146  }
147 
148  /*!
149  * \brief Bind attribute buffer
150  *
151  * This is a variant of bindBuffer() that allows to bind a member variable
152  * of an object as attribute buffer. The object can be part of a container
153  * that stores the objects contiguously (e.g. std::vector, std::array) and
154  * the stride is automatically derived from the object size.
155  *
156  * \see bindBuffer()
157  */
158  template <typename ObjectType, typename MemberPointer>
160  const std::string &attribute, //!< [in] attribute name
161  const ObjectType &object, //!< [in] e.g. first object of container
162  const MemberPointer member //!< [in] object member variable pointer
163  )
164  {
165  bindBuffer(
166  attribute, object.*member,
167  static_cast<int32_t>(sizeof(ObjectType))
168  );
169  }
170 
171  //! \copydoc bindMember()
172  template <typename ObjectType, typename MemberPointer>
174  const std::string &attribute, //!< [in] attribute name
175  const ObjectType &object, //!< [in] e.g. first object of container
176  const MemberPointer member, //!< [in] object member variable pointer
177  const size_t index //!< [in] index for array-like object members
178  )
179  {
180  bindBuffer(
181  attribute, (object.*member)[index],
182  static_cast<int32_t>(sizeof(ObjectType))
183  );
184  }
185 
186  /*!
187  * \brief Update points
188  *
189  * Use this function to actually read the point attributes from
190  * all defined buffers and update the points in the database.
191  *
192  * Afterwards you may re-fill the buffers or define new buffers
193  * with bind() and call next() again until all points have been
194  * updated.
195  *
196  * \remark It is assumed that the points are given in the exact same order as
197  * returned by the select query (riegl::rdb::pointcloud::QuerySelect).
198  * If the points are given in a different order, the update will still
199  * work but may take more time to finish. Of course it is not required
200  * to update all points (you don't need to provide points that you do
201  * not want to update).
202  *
203  * \note IEEE-754 "NaN" values contained in floating point source
204  * buffers are ignored and the attribute's default value is
205  * used instead. Furthermore IEEE-754 "Infinity" values will
206  * always cause next() to fail with error code 10414, i.e.
207  * riegl::rdb::Error::QueryAttributeValueOutOfRange.
208  *
209  * \warning If you want to modify the primary point attribute (usually
210  * the point coordinates), you __must__ either read __all__ points
211  * with a select query (class QuerySelect) first and update them
212  * later, or use two different instances of riegl::rdb::Pointcloud
213  * on the same database and use one instance to read (select) and
214  * the other instance to write (update) the points. In other words:
215  * It is not allowed to alternately call next() on an instance of
216  * QuerySelect and an instance of QueryUpdate if both were started
217  * on the same Pointcloud instance and the goal is to modify the
218  * primary point attribute.
219  *
220  * \returns the number of points updated
221  */
222  uint32_t next(
223  uint32_t count //!< [in] size of source buffers in terms of points
224  );
225 
226 private:
227  struct Private;
228  std::shared_ptr<Private> data;
229 };
230 
231 }}} // namespace riegl::rdb::pointcloud
232 
233 #endif // RIEGL_RDB_POINTCLOUD_QUERYUPDATE_HPP
riegl::rdb::pointcloud::QueryUpdate::valid
bool valid() const
Check if query is not null.
riegl::rdb::pointcloud::QueryUpdate::bindMember
void bindMember(const std::string &attribute, const ObjectType &object, const MemberPointer member, const size_t index)
Bind attribute buffer.
Definition: queryUpdate.hpp:173
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:146
riegl::rdb::pointcloud::QueryUpdate::close
void close()
Finish query.
riegl::rdb::pointcloud::QueryUpdate::next
uint32_t next(uint32_t count)
Update points.
riegl::rdb::pointcloud::QueryUpdate::bindBuffer
void bindBuffer(const std::string &attribute, const ValueType &buffer, const int32_t stride=0)
Bind attribute buffer.
Definition: queryUpdate.hpp:139
dataTypes.hpp
Point attribute access data types.
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:175
riegl::rdb::pointcloud::QueryUpdate
Point update query.
Definition: queryUpdate.hpp:64
riegl::rdb::pointcloud::QueryUpdate::bind
void bind(const std::string &attribute, const DataType dataType, const void *buffer, const int32_t stride=0)
Bind attribute buffer.
riegl::rdb::pointcloud::QueryUpdate::bindMember
void bindMember(const std::string &attribute, const ObjectType &object, const MemberPointer member)
Bind attribute buffer.
Definition: queryUpdate.hpp:159
pointcloudData.hpp
Pointcloud class implementation details.
riegl::rdb::pointcloud::QueryUpdate::QueryUpdate
QueryUpdate()
Default constructor.
riegl::rdb::pointcloud::DataType
DataType
Point attribute access data type.
Definition: dataTypes.hpp:55