1
/***************************************************************************
2
* Copyright (c) 2011 Werner Mayer <wmayer[at]users.sourceforge.net> *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
23
#include "PreCompiled.h"
25
#pragma warning(disable : 4396)
29
#include <kdtree++/kdtree.hpp>
32
using namespace MeshCore;
36
using value_type = float;
38
Point3d(const Base::Vector3f& f, PointIndex i)
43
Point3d(const Point3d& pnt) = default;
45
Point3d(Point3d&& pnt)
52
inline value_type operator[](const int N) const
57
inline bool operator==(const Point3d& other) const
59
return (this->p) == (other.p);
62
inline bool operator!=(const Point3d& other) const
64
return (this->p) != (other.p);
67
inline Point3d& operator=(const Point3d& other) = default;
69
inline Point3d& operator=(Point3d&& other)
80
using MyKDTree = KDTree::KDTree<3, Point3d>;
82
class MeshKDTree::Private
88
MeshKDTree::MeshKDTree()
92
MeshKDTree::MeshKDTree(const std::vector<Base::Vector3f>& points)
96
for (auto it : points) {
97
d->kd_tree.insert(Point3d(it, index++));
101
MeshKDTree::MeshKDTree(const MeshPointArray& points)
104
PointIndex index = 0;
105
for (const auto& it : points) {
106
d->kd_tree.insert(Point3d(it, index++));
110
MeshKDTree::~MeshKDTree()
115
void MeshKDTree::AddPoint(const Base::Vector3f& point)
117
PointIndex index = d->kd_tree.size();
118
d->kd_tree.insert(Point3d(point, index));
121
void MeshKDTree::AddPoints(const std::vector<Base::Vector3f>& points)
123
PointIndex index = d->kd_tree.size();
124
for (auto it : points) {
125
d->kd_tree.insert(Point3d(it, index++));
129
void MeshKDTree::AddPoints(const MeshPointArray& points)
131
PointIndex index = d->kd_tree.size();
132
for (const auto& it : points) {
133
d->kd_tree.insert(Point3d(it, index++));
137
bool MeshKDTree::IsEmpty() const
139
return d->kd_tree.empty();
142
void MeshKDTree::Clear()
147
void MeshKDTree::Optimize()
149
d->kd_tree.optimize();
152
PointIndex MeshKDTree::FindNearest(const Base::Vector3f& p, Base::Vector3f& n, float& dist) const
154
std::pair<MyKDTree::const_iterator, MyKDTree::distance_type> it =
155
d->kd_tree.find_nearest(Point3d(p, 0));
156
if (it.first == d->kd_tree.end()) {
157
return POINT_INDEX_MAX;
159
PointIndex index = it.first->i;
165
PointIndex MeshKDTree::FindNearest(const Base::Vector3f& p,
170
std::pair<MyKDTree::const_iterator, MyKDTree::distance_type> it =
171
d->kd_tree.find_nearest(Point3d(p, 0), max_dist);
172
if (it.first == d->kd_tree.end()) {
173
return POINT_INDEX_MAX;
175
PointIndex index = it.first->i;
181
PointIndex MeshKDTree::FindExact(const Base::Vector3f& p) const
183
MyKDTree::const_iterator it = d->kd_tree.find_exact(Point3d(p, 0));
184
if (it == d->kd_tree.end()) {
185
return POINT_INDEX_MAX;
187
PointIndex index = it->i;
191
void MeshKDTree::FindInRange(const Base::Vector3f& p,
193
std::vector<PointIndex>& indices) const
195
std::vector<Point3d> v;
196
d->kd_tree.find_within_range(Point3d(p, 0), range, std::back_inserter(v));
197
indices.reserve(v.size());
198
for (const auto& it : v) {
199
indices.push_back(it.i);