示例#1
0
void Octree::getFullLeafsNearPlane(const double* p, const double* n, double dist, list<OctreeNode*>& out)
{
	list<OctreeNode*> nodes;
	nodes.push_back(mRoot);
	int i;

	while ( nodes.size() )
	{
		// Get the last element in the list
		OctreeNode* node = nodes.back();
		// Remove the last element from the list
		nodes.pop_back();

		// Check if the sphere intersects the current node
		if ( fabs(Vector::signedDistToPlane3(p, n, node->getCenter())) <= dist + node->getVoxelRadius() )
		{
			// We have an intersection -> push back the children of the current node
			if ( node->hasChildren() )
			{
				for ( i = 0 ; i < 8 ; ++i )
					nodes.push_back(node->getChild(i));
			}
			else if ( node->isFull() )
				out.push_back(node);
		}
	}
}
示例#2
0
void Octree::getFullLeafsWithinSphere(double* p, double radius, list<OctreeNode*>& out)
{
	list<OctreeNode*> nodes;
	nodes.push_back(mRoot);
	int i;
	double nodeCenterToSphereCenterDist;

	while ( nodes.size() )
	{
		// Get the last element in the list
		OctreeNode* node = nodes.back();
		// Remove the last element from the list
		nodes.pop_back();

		// Get the distance between the node center and the sphere center
		nodeCenterToSphereCenterDist = Vector::dist3(p, node->getCenter());

		// Check if the current node is completely contained in the sphere.
		// If yes -> add all its full children to 'out'.
		if ( nodeCenterToSphereCenterDist + node->getVoxelRadius() <= radius )
			this->pushBackFullLeafsFromNode(node, out);
		// Check if the sphere intersects the current node
		else if ( fabs(radius - nodeCenterToSphereCenterDist) <= node->getVoxelRadius() )
		{
			// We have an intersection -> push back the children of the current node
			if ( node->hasChildren() )
				for ( i = 0 ; i < 8 ; ++i )
					nodes.push_back(node->getChild(i));
			else if ( node->isFull() )
				out.push_back(node);
		}
	}
}
示例#3
0
void Octree::fillOctree()
{
	double p[3];
	const double *center;
	int i, l, id, numOfPoints = mInputPoints->GetNumberOfPoints();
	OctreeNode* node;

	for ( i = 0 ; i < numOfPoints ; ++i )
	{
		// Some initialization
		mInputPoints->GetPoint(i, p);
		node = mRoot;

		// Go down to the right leaf
		for ( l = 0 ; l < mTreeLevels ; ++l )
		{
			node->createChildren(); // If this node already has children -> nothing will happen
			center = node->getCenter();
			id = 0;

			if ( p[0] >= center[0] ) id |= 4;
			if ( p[1] >= center[1] ) id |= 2;
			if ( p[2] >= center[2] ) id |= 1;

			node->fullDescendantsFlagsBitwiseOR((unsigned char)0x01 << id);
			node = node->getChild(id);
		}

		this->fillOctreeLeaf(node, i, p);
	}
}
示例#4
0
void Octree::buildFullLeafsVectorAndNeighbourhoodStructure()
{
	if ( !mRoot )
		return;

	int i;
	OctreeNode* node;
	list<OctreeNode*> nodes;

	// Init
	nodes.push_back(mRoot);
	mFullLeafs.clear();
	mBoundsOfFullLeafs[0] = mBounds[1]; // set min x to the max x of the whole tree
	mBoundsOfFullLeafs[1] = mBounds[0]; // set max x to the min x of the whole tree
	mBoundsOfFullLeafs[2] = mBounds[3]; // ...
	mBoundsOfFullLeafs[3] = mBounds[2];
	mBoundsOfFullLeafs[4] = mBounds[5];
	mBoundsOfFullLeafs[5] = mBounds[4];

	while ( nodes.size() )
	{
		node = nodes.back();
		nodes.pop_back();

		if ( node->hasChildren() )
			for ( i = 0 ; i < 8 ; ++i )
				nodes.push_back(node->getChild(i));
		else if ( node->hasData() )
		{
			if ( node->getBounds()[0] < mBoundsOfFullLeafs[0] ) mBoundsOfFullLeafs[0] = node->getBounds()[0];
			if ( node->getBounds()[2] < mBoundsOfFullLeafs[2] ) mBoundsOfFullLeafs[2] = node->getBounds()[2];
			if ( node->getBounds()[4] < mBoundsOfFullLeafs[4] ) mBoundsOfFullLeafs[4] = node->getBounds()[4];

			if ( node->getBounds()[1] > mBoundsOfFullLeafs[1] ) mBoundsOfFullLeafs[1] = node->getBounds()[1];
			if ( node->getBounds()[3] > mBoundsOfFullLeafs[3] ) mBoundsOfFullLeafs[3] = node->getBounds()[3];
			if ( node->getBounds()[5] > mBoundsOfFullLeafs[5] ) mBoundsOfFullLeafs[5] = node->getBounds()[5];

			mFullLeafs.push_back(node);
			this->collectFullNeighbours(node);
		}
	}
	this->sortFullLeafsVector();
}
示例#5
0
void Octree::getFullLeafsInRange(double* p, double r1, double r2, list<OctreeNode*>& out)
{
	list<OctreeNode*> nodes;
	nodes.push_back(mRoot);
	int i;
	double d1, d2, dist;

	while ( nodes.size() )
	{
		// Get the last element in the list
		OctreeNode* node = nodes.back();
		// Remove the last element in the list
		nodes.pop_back();

#ifdef OCTREE_TEST_MODE
		++mNodeRangeTestCounter;
#endif

		// Get the distance between the sphere radius and the node center
		dist = Vector::dist3(p, node->getCenter());
		d1 = dist + node->getVoxelRadius();
		d2 = dist - node->getVoxelRadius();

		if ( d1 >= r1 && d2 <= r2 )
		{
			// Check if we have the special case that the voxel is completely between both spheres
			if ( d1 <= r2 && d2 >= r1 )
				this->pushBackFullLeafsFromNode(node, out);
			else
			{
				if ( node->hasChildren() )
				{
					// Push back the children for further processing
					for ( i = 0 ; i < 8 ; ++i )
						nodes.push_back(node->getChild(i));
				}
				// We have reached a leaf -> save it in 'out' if it's full
				else if ( node->isFull() )
					out.push_back(node);
			}
		}
	}
}
示例#6
0
OctreeNode* Octree::getRandomFullLeafOnSphere(const double* p, double radius) const
{
	list<OctreeNode*> nodes;
	nodes.push_back(mRoot);
	int i, rand_id;
	vector<int> tmp_ids;
	tmp_ids.reserve(8);

	while ( nodes.size() )
	{
		// Get the last element in the list
		OctreeNode* node = nodes.back();
		// Remove the last element from the list
		nodes.pop_back();

		// Check if the sphere intersects the current node
		if ( fabs(radius - Vector::dist3(p, node->getCenter())) <= node->getVoxelRadius() )
		{
			// We have an intersection -> push back the children of the current node
			if ( node->hasChildren() )
			{
				// Prepare the tmp id vector
				for ( i = 0 ; i < 8 ; ++i )
					tmp_ids.push_back(i);

				// Push back the children in random order
				for ( i = 0 ; i < 8 ; ++i )
				{
					rand_id = mRandGen.getRandomInteger(0, tmp_ids.size()-1);
					nodes.push_back(node->getChild(tmp_ids[rand_id]));
					// Remove the randomly selected id
					tmp_ids.erase(tmp_ids.begin() + rand_id);
				}
			}
			else if ( node->isFull() )
				return node;
		}
	}

	return NULL;
}
示例#7
0
void Octree::buildNeighbourhoodStructure()
{
	if ( !mRoot )
		return;

	int i;
	OctreeNode* node;
	list<OctreeNode*> nodes;
	nodes.push_back(mRoot);

	while ( nodes.size() )
	{
		node = nodes.back();
		nodes.pop_back();

		if ( node->hasChildren() )
			for ( i = 0 ; i < 8 ; ++i )
				nodes.push_back(node->getChild(i));
		else if ( node->hasData() )
			this->collectFullNeighbours(node);
	}
}
示例#8
0
OctreeNode* Octree::getRandomFullLeaf()
{
	list<OctreeNode*> nodes;
	nodes.push_back(mRoot);
	int i, rand_id;
	vector<int> tmp_ids;
	tmp_ids.reserve(8);

	while ( nodes.size() )
	{
		// Get the last element in the list
		OctreeNode* node = nodes.back();
		// Remove the last element from the list
		nodes.pop_back();

		// Push back the children of the current node
		if ( node->hasChildren() )
		{
			// Prepare the tmp id vector
			for ( i = 0 ; i < 8 ; ++i )
				tmp_ids.push_back(i);

			// Push back the children in random order
			for ( i = 0 ; i < 8 ; ++i )
			{
				rand_id = mRandGen.getRandomInteger(0, tmp_ids.size()-1);
				nodes.push_back(node->getChild(tmp_ids[rand_id]));
				// Remove the randomly selected id
				tmp_ids.erase(tmp_ids.begin() + rand_id);
			}
		}
		else if ( node->isFull() )
			return node;
	}

	return NULL;
}