RDB 2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
queryInsert.hpp
Go to the documentation of this file.
1 /*
2  *******************************************************************************
3  *
4  * Copyright 2023 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 queryInsert.hpp
26  * \author RIEGL LMS GmbH, Austria
27  * \brief Point insert 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  * \version 2020-02-27/AW: Add bindId() for "riegl.id" data buffers (#3576)
33  *
34  *******************************************************************************
35  */
36 
37 #ifndef RIEGL_RDB_POINTCLOUD_QUERYINSERT_HPP
38 #define RIEGL_RDB_POINTCLOUD_QUERYINSERT_HPP
39 
40 //---< INCLUDES >---------------------------------------------------------------
41 
42 #include <memory>
43 #include <string>
44 #include <cstdlib>
45 #include <cstdint>
46 
49 
50 //---< NAMESPACE >--------------------------------------------------------------
51 
52 namespace riegl {
53 namespace rdb {
54 namespace pointcloud {
55 
56 //---< CLASS QueryInsert >------------------------------------------------------
57 /*!
58  * \brief Point insert query
59  *
60  * This class can be used to insert (new) points into the database.
61  *
62  * \see riegl::rdb::Pointcloud::insert()
63  *
64  * \note You either must delete the query object or call close()
65  * __before__ the parent Pointcloud instance is closed/deleted!
66  */
68 {
69 public:
70  /*!
71  * \brief Default constructor
72  *
73  * Creates a null query - i.e. the query cannot be used to insert points.
74  *
75  * \see riegl::rdb::Pointcloud::insert()
76  */
77  explicit QueryInsert();
78 
79  /*!
80  * \brief Constructor
81  *
82  * Creates a query prepared for inserting points.
83  *
84  * \note You cannot create new QueryInsert objects this way,
85  * use riegl::rdb::Pointcloud::insert() instead.
86  */
87  explicit QueryInsert(riegl::rdb::PointcloudData *pointcloud);
88 
89  /*!
90  * \brief Check if query is not null
91  *
92  * \see valid()
93  */
94  operator bool() const;
95 
96  /*!
97  * \brief Check if query is not null
98  *
99  * A null query cannot be used to insert points.
100  */
101  bool valid() const;
102 
103  /*!
104  * \brief Finish query
105  *
106  * Call this function when done with inserting points.
107  */
108  void close();
109 
110  /*!
111  * \brief Bind attribute buffer
112  *
113  * Use this function to define a source buffer for a point attribute.
114  * Exactly one buffer can be defined for an attribute (i.e. only the
115  * most recently defined buffer will be used).
116  *
117  * You can but don't need to define a buffer for each attribute. If
118  * no buffer is defined for an attribute, the attribute's default
119  * value will be used instead.
120  *
121  * The buffer is expected to be n*s*d bytes large, where
122  * __n__ is the number of points defined in next(),
123  * __s__ is the size of one element as defined by 'dataType' and
124  * __d__ is the number of attribute dimensions (elements).
125  *
126  * \note This function just stores the buffer pointer - it does
127  * __NOT__ copy the data contained in the buffer. So make
128  * sure that the buffer remains valid until you call next().
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  /*!
140  * \brief Bind point id buffer
141  *
142  * If you provide a buffer for the point identifier attribute ("riegl.id"),
143  * then it will receive the identifiers of the inserted points (PID). Each
144  * point is assigned a unique PID on insertion. The PID starts at 1 for the
145  * first point and is incremented by 1 for each subsequent point (so that
146  * the PID reflects the insertion order of the points, but only as long as
147  * riegl::rdb::pointcloud::CreateSettings::optimizePointID is set to false).
148  *
149  * \see bind()
150  */
151  void bindId(
152  const DataType dataType, //!< [in] buffer data type
153  void *buffer, //!< [in] buffer location
154  const std::int32_t stride = 0 //!< [in] bytes between beginnings of successive elements (0: auto)
155  );
156 
157  //! \copydoc bind()
158  template <typename ValueType>
160  const std::string &attribute, //!< [in] attribute name
161  const ValueType &buffer, //!< [in] buffer (data, pointer to data, std::array or std::vector)
162  const std::int32_t stride = 0 //!< [in] bytes between beginnings of successive elements (0: auto)
163  )
164  {
165  bind(attribute, dataTypeOf(buffer), dataPointerOf(buffer), stride);
166  }
167 
168  /*!
169  * \copydoc bindId()
170  * \see bindBuffer()
171  */
172  template <typename ValueType>
174  ValueType &buffer, //!< [in] buffer (data, pointer to data, std::array or std::vector)
175  const std::int32_t stride = 0 //!< [in] bytes between beginnings of successive elements (0: auto)
176  )
177  {
178  bindId(dataTypeOf(buffer), dataPointerOf(buffer), stride);
179  }
180 
181  /*!
182  * \copydoc bindId()
183  * \see bindBuffer()
184  */
185  template <typename ValueType>
187  ValueType *buffer, //!< [in] buffer (data, pointer to data, std::array or std::vector)
188  const std::int32_t stride = 0 //!< [in] bytes between beginnings of successive elements (0: auto)
189  )
190  {
191  bindId(dataTypeOf(buffer), buffer, stride);
192  }
193 
194  /*!
195  * \brief Bind attribute buffer
196  *
197  * This is a variant of bindBuffer() that allows to bind a member variable
198  * of an object as attribute buffer. The object can be part of a container
199  * that stores the objects contiguously (e.g. std::vector, std::array) and
200  * the stride is automatically derived from the object size.
201  *
202  * \see bindBuffer()
203  */
204  template <typename ObjectType, typename MemberPointer>
206  const std::string &attribute, //!< [in] attribute name
207  const ObjectType &object, //!< [in] e.g. first object of container
208  const MemberPointer member //!< [in] object member variable pointer
209  )
210  {
211  bindBuffer(
212  attribute, object.*member,
213  static_cast<std::int32_t>(sizeof(ObjectType))
214  );
215  }
216 
217  /*!
218  * \copydoc bindId()
219  * \see bindMember()
220  */
221  template <typename ObjectType, typename MemberPointer>
223  ObjectType &object, //!< [in] e.g. first object of container
224  MemberPointer member //!< [in] object member variable pointer
225  )
226  {
227  bindIdBuffer(
228  object.*member,
229  static_cast<std::int32_t>(sizeof(ObjectType))
230  );
231  }
232 
233  //! \copydoc bindMember()
234  template <typename ObjectType, typename MemberPointer>
236  const std::string &attribute, //!< [in] attribute name
237  const ObjectType &object, //!< [in] e.g. first object of container
238  const MemberPointer member, //!< [in] object member variable pointer
239  const std::size_t index //!< [in] index for array-like object members
240  )
241  {
242  bindBuffer(
243  attribute, (object.*member)[index],
244  static_cast<std::int32_t>(sizeof(ObjectType))
245  );
246  }
247 
248  /*!
249  * \copydoc bindId()
250  * \see bindMember()
251  */
252  template <typename ObjectType, typename MemberPointer>
254  ObjectType &object, //!< [in] e.g. first object of container
255  MemberPointer member, //!< [in] object member variable pointer
256  const std::size_t index //!< [in] index for array-like object members
257  )
258  {
259  bindIdBuffer(
260  (object.*member)[index],
261  static_cast<std::int32_t>(sizeof(ObjectType))
262  );
263  }
264 
265  /*!
266  * \brief Insert points
267  *
268  * Use this function to actually read the point attributes from
269  * all defined buffers and insert the points into the database.
270  *
271  * Afterwards you may re-fill the buffers or define new buffers
272  * with bind() and call next() again until all points have been
273  * inserted.
274  *
275  * \note IEEE-754 "NaN" values contained in floating point source
276  * buffers are ignored and the attribute's default value is
277  * used instead. Furthermore IEEE-754 "Infinity" values will
278  * always cause next() to fail with error code 10414, i.e.
279  * riegl::rdb::Error::QueryAttributeValueOutOfRange.
280  *
281  * \note Since version 2.4.2, unit vector point attributes (e.g.
282  * "riegl.direction") are automatically normalized (divided
283  * by the vector length) on insertion. This is done for all
284  * point attributes that meet the following requirements:
285  * `length` is 3, `minimumValue` is -1, `maximumValue` is 1,
286  * `resolution` is not 1, `scaleFactor` is 1, `unitSymbol` is
287  * empty, `invalidValue` is undefined and `tags` contains the
288  * "direction" tag but not the "do-not-normalize" tag.
289  *
290  * \returns the number of points inserted
291  */
292  std::uint32_t next(
293  std::uint32_t count //!< [in] size of source buffers in terms of points
294  );
295 
296 private:
297  struct Private;
298  std::shared_ptr<Private> data;
299 };
300 
301 }}} // namespace riegl::rdb::pointcloud
302 
303 #endif // RIEGL_RDB_POINTCLOUD_QUERYINSERT_HPP
void bindMember(const std::string &attribute, const ObjectType &object, const MemberPointer member)
Bind attribute buffer.
DataType
Point attribute access data type.
Definition: dataTypes.hpp:56
void bind(const std::string &attribute, const DataType dataType, const void *buffer, const std::int32_t stride=0)
Bind attribute buffer.
ValueType * dataPointerOf(ValueType *const value)
Get pointer to variable or to data in a std::array or vector container.
Definition: dataTypes.hpp:176
void bindIdMember(ObjectType &object, MemberPointer member, const std::size_t index)
Bind point id buffer.
bool valid() const
Check if query is not null.
DataType dataTypeOf()
Convenience wrapper for DataTypeOf class.
Definition: dataTypes.hpp:147
void bindIdBuffer(ValueType &buffer, const std::int32_t stride=0)
Bind point id buffer.
std::uint32_t next(std::uint32_t count)
Insert points.
void bindIdMember(ObjectType &object, MemberPointer member)
Bind point id buffer.
void bindId(const DataType dataType, void *buffer, const std::int32_t stride=0)
Bind point id buffer.
void bindBuffer(const std::string &attribute, const ValueType &buffer, const std::int32_t stride=0)
Bind attribute buffer.
Point attribute access data types.
Pointcloud class implementation details.
void bindMember(const std::string &attribute, const ObjectType &object, const MemberPointer member, const std::size_t index)
Bind attribute buffer.
void bindIdBuffer(ValueType *buffer, const std::int32_t stride=0)
Bind point id buffer.
QueryInsert()
Default constructor.