EasyNav Plugins
Loading...
Searching...
No Matches
grid_coord.hpp
Go to the documentation of this file.
1/*
2 * Copyright Contributors to the Bonxai Project
3 * Copyright Contributors to the OpenVDB Project
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
8 */
9
10#pragma once
11
12#include <array>
13#include <cmath>
14#include <cstddef>
15#include <stdexcept>
16#include <type_traits>
17#include <vector>
18
19namespace Bonxai
20{
21
22// Magically converts any representation of a point in 3D
23// (type with x, y and z) to another one. Works with:
24//
25// - pcl::PointXYZ, pcl::PointXYZI, pcl::PointXYZRGB, etc
26// - Eigen::Vector3d, Eigen::Vector3f
27// - custom type with x,y,z fields. In this case Bonxai::Point3D
28// - arrays or vectors with 3 elements.
29
30template<typename PointOut, typename PointIn>
31PointOut ConvertPoint(const PointIn & v);
32
33struct Point3D
34{
35 double x;
36 double y;
37 double z;
38
39 Point3D() = default;
40
41 Point3D(const Point3D & v) = default;
42 Point3D(Point3D && v) = default;
43
44 Point3D & operator=(const Point3D & v) = default;
45 Point3D & operator=(Point3D && v) = default;
46
47 Point3D(double x, double y, double z);
48
49 template<typename T>
50 Point3D(const T & v)
51 {
52 *this = ConvertPoint<Point3D>(v);
53 }
54
55 template<typename T>
56 Point3D & operator=(const T & v)
57 {
58 *this = ConvertPoint<Point3D>(v);
59 return *this;
60 }
61
62 // Access to x, y, z, using index 0, 1, 2
63 [[nodiscard]] double & operator[](size_t index);
64};
65
66struct CoordT
67{
68 int32_t x;
69 int32_t y;
70 int32_t z;
71
72 // Access to x, y, z, using index 0, 1, 2
73 [[nodiscard]] int32_t & operator[](size_t index);
74
75 [[nodiscard]] bool operator==(const CoordT & other) const;
76 [[nodiscard]] bool operator!=(const CoordT & other) const;
77
78 [[nodiscard]] CoordT operator+(const CoordT & other) const;
79 [[nodiscard]] CoordT operator-(const CoordT & other) const;
80
81 CoordT & operator+=(const CoordT & other);
82 CoordT & operator-=(const CoordT & other);
83};
84
85[[nodiscard]] inline CoordT PosToCoord(const Point3D & point, double inv_resolution)
86{
87 return {
88 static_cast<int32_t>(std::floor(point.x * inv_resolution)),
89 static_cast<int32_t>(std::floor(point.y * inv_resolution)),
90 static_cast<int32_t>(std::floor(point.z * inv_resolution))};
91}
92
93[[nodiscard]] inline Point3D CoordToPos(const CoordT & coord, double resolution)
94{
95 return {
96 (static_cast<double>(coord.x)) * resolution, (static_cast<double>(coord.y)) * resolution,
97 (static_cast<double>(coord.z)) * resolution};
98}
99
100//----------------------------------------------------
101//----------------- Implementations ------------------
102//----------------------------------------------------
103
104inline Point3D::Point3D(double _x, double _y, double _z)
105: x(_x),
106 y(_y),
107 z(_z) {}
108
109inline double & Point3D::operator[](size_t index)
110{
111 switch (index) {
112 case 0:
113 return x;
114 case 1:
115 return y;
116 case 2:
117 return z;
118 default:
119 throw std::runtime_error("out of bound index");
120 }
121}
122
123// clang-format off
124template<class T, class = void>
125struct type_has_method_x : std::false_type {};
126template<class T>
127struct type_has_method_x<T, std::void_t<decltype(T().x())>>: std::true_type {};
128
129template<class T, class = void>
130struct type_has_member_x : std::false_type {};
131template<class T>
132struct type_has_member_x<T, std::void_t<decltype(T::x)>>: std::true_type {};
133
134template<typename>
135struct type_is_vector : std::false_type {};
136template<typename T, typename A>
137struct type_is_vector<std::vector<T, A>>: std::true_type {};
138template<typename T>
139struct type_is_vector<std::array<T, 3>>: std::true_type {};
140// clang-format on
141
142template<typename PointOut, typename PointIn>
143inline PointOut ConvertPoint(const PointIn & v)
144{
145 // clang-format off
146 static_assert(std::is_same_v<PointIn, PointOut>||
150 "Can't convert from the specified type");
151
152 static_assert(std::is_same_v<PointIn, PointOut>||
156 "Can't convert to the specified type");
157
158 // clang-format on
159 if constexpr (std::is_same_v<PointIn, PointOut>) {
160 return v;
161 }
162 if constexpr (type_has_method_x<PointIn>::value) {
163 return {v.x(), v.y(), v.z()};
164 }
165 if constexpr (type_has_member_x<PointIn>::value) {
166 return {v.x, v.y, v.z};
167 }
168 if constexpr (type_is_vector<PointIn>::value) {
169 return {v[0], v[1], v[2]};
170 }
171}
172
173inline int32_t & CoordT::operator[](size_t index)
174{
175 switch (index) {
176 case 0:
177 return x;
178 case 1:
179 return y;
180 case 2:
181 return z;
182 default:
183 throw std::runtime_error("out of bound index");
184 }
185}
186
187inline bool CoordT::operator==(const CoordT & other) const
188{
189 return x == other.x && y == other.y && z == other.z;
190}
191
192inline bool CoordT::operator!=(const CoordT & other) const
193{
194 return !(*this == other);
195}
196
197inline CoordT CoordT::operator+(const CoordT & other) const
198{
199 return {x + other.x, y + other.y, z + other.z};
200}
201
202inline CoordT CoordT::operator-(const CoordT & other) const
203{
204 return {x - other.x, y - other.y, z - other.z};
205}
206
207inline CoordT & CoordT::operator+=(const CoordT & other)
208{
209 x += other.x;
210 y += other.y;
211 z += other.z;
212 return *this;
213}
214
215inline CoordT & CoordT::operator-=(const CoordT & other)
216{
217 x -= other.x;
218 y -= other.y;
219 z -= other.z;
220 return *this;
221}
222
223} // namespace Bonxai
224
225namespace std
226{
227template<>
228struct hash<Bonxai::CoordT>
229{
230 std::size_t operator()(const Bonxai::CoordT & p) const
231 {
232 // same as OpenVDB
233 return ((1 << 20) - 1) & (static_cast<int64_t>(p.x) * 73856093 ^ //
234 static_cast<int64_t>(p.y) * 19349669 ^ //
235 static_cast<int64_t>(p.z) * 83492791);
236 }
237};
238
239} // namespace std
Definition bonxai.hpp:28
CoordT PosToCoord(const Point3D &point, double inv_resolution)
Definition grid_coord.hpp:85
Point3D CoordToPos(const CoordT &coord, double resolution)
Definition grid_coord.hpp:93
PointOut ConvertPoint(const PointIn &v)
Definition grid_coord.hpp:143
Definition grid_coord.hpp:226
Definition grid_coord.hpp:67
CoordT & operator-=(const CoordT &other)
Definition grid_coord.hpp:215
bool operator==(const CoordT &other) const
Definition grid_coord.hpp:187
CoordT operator+(const CoordT &other) const
Definition grid_coord.hpp:197
int32_t & operator[](size_t index)
Definition grid_coord.hpp:173
CoordT operator-(const CoordT &other) const
Definition grid_coord.hpp:202
bool operator!=(const CoordT &other) const
Definition grid_coord.hpp:192
int32_t z
Definition grid_coord.hpp:70
CoordT & operator+=(const CoordT &other)
Definition grid_coord.hpp:207
int32_t y
Definition grid_coord.hpp:69
int32_t x
Definition grid_coord.hpp:68
Definition grid_coord.hpp:34
Point3D & operator=(const T &v)
Definition grid_coord.hpp:56
double & operator[](size_t index)
Definition grid_coord.hpp:109
Point3D(const T &v)
Definition grid_coord.hpp:50
Point3D()=default
Point3D & operator=(Point3D &&v)=default
Point3D(Point3D &&v)=default
double z
Definition grid_coord.hpp:37
double y
Definition grid_coord.hpp:36
Point3D & operator=(const Point3D &v)=default
double x
Definition grid_coord.hpp:35
Point3D(const Point3D &v)=default
Definition grid_coord.hpp:130
Definition grid_coord.hpp:125
Definition grid_coord.hpp:135
std::size_t operator()(const Bonxai::CoordT &p) const
Definition grid_coord.hpp:230