Files
create/src/Mod/Mesh/App/Core/KDTree.cpp
wmayer be8634d05c Handle clang 10 warnings:
+ fix -Wtautological-bitwise-compare
+ fix -Wimplicit-int-float-conversion
+ fix -Wmisleading-indentation
+ fix -Wrange-loop-construct
+ suppress -Wdeprecated-copy of 3rd party libs
2020-05-25 15:34:43 +02:00

188 lines
5.4 KiB
C++

/***************************************************************************
* Copyright (c) 2011 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifdef _MSC_VER
# pragma warning(disable : 4396)
#endif
#ifndef _PreComp_
#endif
#if defined(__clang__) && defined(__has_warning)
#if __has_warning("-Wdeprecated-copy")
# pragma clang diagnostic ignored "-Wdeprecated-copy"
#endif
#endif
#include "KDTree.h"
#include <kdtree++/kdtree.hpp>
using namespace MeshCore;
struct Point3d
{
typedef float value_type;
Point3d(const Base::Vector3f& f, unsigned long i) : p(f), i(i)
{
}
inline value_type operator[](const int N) const
{
return p[N];
}
inline bool operator==(const Point3d& other) const
{
return (this->p) == (other.p);
}
inline bool operator!=(const Point3d& other) const
{
return (this->p) != (other.p);
}
inline void operator=(const Point3d& other)
{
this->p = other.p;
this->i = other.i;
}
Base::Vector3f p;
unsigned long i;
};
typedef KDTree::KDTree<3, Point3d> MyKDTree;
class MeshKDTree::Private
{
public:
MyKDTree kd_tree;
};
MeshKDTree::MeshKDTree() : d(new Private)
{
}
MeshKDTree::MeshKDTree(const std::vector<Base::Vector3f>& points) : d(new Private)
{
unsigned long index=0;
for (std::vector<Base::Vector3f>::const_iterator it = points.begin(); it != points.end(); ++it) {
d->kd_tree.insert(Point3d(*it, index++));
}
}
MeshKDTree::MeshKDTree(const MeshPointArray& points) : d(new Private)
{
unsigned long index=0;
for (MeshPointArray::_TConstIterator it = points.begin(); it != points.end(); ++it) {
d->kd_tree.insert(Point3d(*it, index++));
}
}
MeshKDTree::~MeshKDTree()
{
delete d;
}
void MeshKDTree::AddPoint(Base::Vector3f& point)
{
unsigned long index=d->kd_tree.size();
d->kd_tree.insert(Point3d(point, index));
}
void MeshKDTree::AddPoints(const std::vector<Base::Vector3f>& points)
{
unsigned long index=d->kd_tree.size();
for (std::vector<Base::Vector3f>::const_iterator it = points.begin(); it != points.end(); ++it) {
d->kd_tree.insert(Point3d(*it, index++));
}
}
void MeshKDTree::AddPoints(const MeshPointArray& points)
{
unsigned long index=d->kd_tree.size();
for (MeshPointArray::_TConstIterator it = points.begin(); it != points.end(); ++it) {
d->kd_tree.insert(Point3d(*it, index++));
}
}
bool MeshKDTree::IsEmpty() const
{
return d->kd_tree.empty();
}
void MeshKDTree::Clear()
{
d->kd_tree.clear();
}
void MeshKDTree::Optimize()
{
d->kd_tree.optimize();
}
unsigned long MeshKDTree::FindNearest(const Base::Vector3f& p, Base::Vector3f& n, float& dist) const
{
std::pair<MyKDTree::const_iterator, MyKDTree::distance_type> it =
d->kd_tree.find_nearest(Point3d(p,0));
if (it.first == d->kd_tree.end())
return ULONG_MAX;
unsigned long index = it.first->i;
n = it.first->p;
dist = it.second;
return index;
}
unsigned long MeshKDTree::FindNearest(const Base::Vector3f& p, float max_dist,
Base::Vector3f& n, float& dist) const
{
std::pair<MyKDTree::const_iterator, MyKDTree::distance_type> it =
d->kd_tree.find_nearest(Point3d(p,0), max_dist);
if (it.first == d->kd_tree.end())
return ULONG_MAX;
unsigned long index = it.first->i;
n = it.first->p;
dist = it.second;
return index;
}
unsigned long MeshKDTree::FindExact(const Base::Vector3f& p) const
{
MyKDTree::const_iterator it =
d->kd_tree.find_exact(Point3d(p,0));
if (it == d->kd_tree.end())
return ULONG_MAX;
unsigned long index = it->i;
return index;
}
void MeshKDTree::FindInRange(const Base::Vector3f& p, float range, std::vector<unsigned long>& indices) const
{
std::vector<Point3d> v;
d->kd_tree.find_within_range(Point3d(p,0), range, std::back_inserter(v));
indices.reserve(v.size());
for (std::vector<Point3d>::iterator it = v.begin(); it != v.end(); ++it)
indices.push_back(it->i);
}