Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KDTree Class pass object via pointer doesn't work #197

Open
538Michael opened this issue Mar 16, 2023 · 1 comment
Open

KDTree Class pass object via pointer doesn't work #197

538Michael opened this issue Mar 16, 2023 · 1 comment

Comments

@538Michael
Copy link

538Michael commented Mar 16, 2023

Hi, I've created a KDTree Class, I call, from main.cpp, another .cpp file to create the KDTree object and then return to me the KDTree object created for searchs, but when the object is passed throw reference, for some reason the dataset is empty.

Heres the code:
KDTree.h

#pragma once
#include "nanoflann.hpp"
#include "Vector3.h"

namespace pathfind
{
	template <typename T>
	struct PointCloud
	{
		struct Point
		{
			T x, y, z;
		};

		using coord_t = T;  //!< The type of each coordinate

		std::vector<Point> pts;

		// Must return the number of data points
		inline size_t kdtree_get_point_count() const { return pts.size(); }

		// Returns the dim'th component of the idx'th point in the class:
		// Since this is inlined and the "dim" argument is typically an immediate
		// value, the
		//  "if/else's" are actually solved at compile time.
		inline T kdtree_get_pt(const size_t idx, const size_t dim) const
		{
			if (dim == 0)
				return pts[idx].x;
			else if (dim == 1)
				return pts[idx].y;
			else
				return pts[idx].z;
		}

		// Optional bounding-box computation: return false to default to a standard
		// bbox computation loop.
		//   Return true if the BBOX was already computed by the class and returned
		//   in "bb" so it can be avoided to redo it again. Look at bb.size() to
		//   find out the expected dimensionality (e.g. 2 or 3 for point clouds)
		template <class BBOX>
		bool kdtree_get_bbox(BBOX& /* bb */) const
		{
			return false;
		}
	};

	class MyKDTree {
	public:
		MyKDTree();
		void buildIndex(PointCloud<float>& cloud);
		size_t findNearestPoint(Vector3 position);

		typedef nanoflann::KDTreeSingleIndexAdaptor<
			nanoflann::L2_Simple_Adaptor<double, PointCloud<float>>,PointCloud<float>,3> KDTreeType;
		KDTreeType* m_kdTree;
	};
}

KDTree.cpp

#pragma once
#include "KDTree.h"
#include <iostream>
#include <fstream>

namespace pathfind
{
	MyKDTree::MyKDTree()
		: m_kdTree(nullptr)
	{
	}

	void MyKDTree::buildIndex(PointCloud<float>& cloud)
	{

		if (m_kdTree != nullptr) {
			delete m_kdTree;
		}
		m_kdTree = new KDTreeType(3, cloud, nanoflann::KDTreeSingleIndexAdaptorParams(10));
		m_kdTree->buildIndex();
	}

	size_t MyKDTree::findNearestPoint(Vector3 position)
	{
		double query_pt[3] = { position.GetX(), position.GetY(), position.GetZ()};

		size_t ret_index;
		double out_dist_sqr;
		nanoflann::KNNResultSet<double> resultSet(1);
		resultSet.init(&ret_index, &out_dist_sqr);
		m_kdTree->findNeighbors(resultSet, &query_pt[0], nanoflann::SearchParams());

		return ret_index;
	}

}

genenerateKDTree.cpp

std::shared_ptr<MyKDTree> generateKDTree()
{
	PointCloud<float> cloud;
	. . .
	// Fill cloud with points
	. . .
	auto kdTree = std::make_shared<MyKDTree>();
	kdTree->buildIndex(cloud);

	// If i run the following code it works as it's intended, but if I call this in main.cpp, it doesn't work
	std::cout << kdTree->findNearestPoint(Vector3(1, 1, 1)) << std::endl;
	
	return kdTree;
}

main.cpp

int main(int argc, char* argv[])
{
	auto kdTree = generateKDTree();
	// When I call this, the dataset of the KDTree is empty.
	std::cout << kdTree->findNearestPoint(Vector3(1, 1, 1)) << std::endl;
}
@Mintpasokon
Copy link
Contributor

In

m_kdTree = new KDTreeType(3, cloud, nanoflann::KDTreeSingleIndexAdaptorParams(10));

cloud are referenced but not copied, by const DatasetAdaptor& KDTreeSingleIndexAdaptor::dataset_.
When 'generateKDTree()' completes, 'cloud' is deconstructed and 'dataset_' becomes a null reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants