Commit c66f7f23 authored by Hans-Christian Ebke's avatar Hans-Christian Ebke
Browse files

Updated BSP Tree implementation with the OpenFlipper/common/bsp

implementation which seemed newer (and better) to me.

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@14114 383ad7c9-94d9-4d36-a494-682f7c89f535
parent a263d854
//=============================================================================
//
// OpenFlipper
// Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
// www.openflipper.org
//
//-----------------------------------------------------------------------------
//
// License
//
// OpenFlipper is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenFlipper 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
// $Revision: 1720 $
// $Author: moebius $
// $Date: 2008-05-09 14:15:53 +0200 (Fri, 09 May 2008) $
//
//=============================================================================
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision: 10745 $ *
* $LastChangedBy: moebius $ *
* $Date: 2011-01-26 10:23:50 +0100 (Wed, 26 Jan 2011) $ *
* *
\*===========================================================================*/
......@@ -48,6 +59,7 @@
//== CLASS DEFINITION =========================================================
#include <vector>
template <class BSPCore>
......@@ -86,8 +98,6 @@ _nearest(Node* _node, NearestNeighborData& _data) const
}
}
}
// non-terminal node
else
......@@ -109,5 +119,69 @@ _nearest(Node* _node, NearestNeighborData& _data) const
}
}
//-----------------------------------------------------------------------------
//=============================================================================
template <class BSPCore>
typename BSPImplT<BSPCore>::RayCollision
BSPImplT<BSPCore>::
raycollision(const Point& _p, const Point& _r) const
{
RayCollisionData data;
data.ref = _p;
data.dist = FLT_MAX;
data.ray = _r;
data.hit_vertices.clear();
_raycollision(this->root_, data);
return RayCollision(data.nearest, data.dist, data.hit_vertices);
}
//-----------------------------------------------------------------------------
template <class BSPCore>
void
BSPImplT<BSPCore>::
_raycollision(Node* _node, RayCollisionData& _data) const
{
// terminal node
if (!_node->left_child_)
{
Scalar dist;
Point v0, v1, v2;
Scalar u, v;
for (HandleIter it=_node->begin(); it!=_node->end(); ++it)
{
this->traits_.points(*it, v0, v1, v2);
if (ACG::Geometry::triangleIntersection(_data.ref, _data.ray, v0, v1, v2, dist, u, v)) {
_data.hit_vertices.push_back(*it);
//face intersects with ray. But is it closer than any that we have found so far?
if (dist < _data.dist)
{
_data.dist = dist;
_data.nearest = *it;
}
}
}
}
// non-terminal node
else
{
Scalar tmin, tmax;
bool used = false;
if ( _node->left_child_ && ACG::Geometry::axisAlignedBBIntersection( _data.ref, _data.ray, _node->left_child_->bb_min, _node->left_child_->bb_max, tmin, tmax)) {
_raycollision(_node->left_child_, _data);
}
if ( _node->right_child_ && ACG::Geometry::axisAlignedBBIntersection( _data.ref, _data.ray, _node->right_child_->bb_min, _node->right_child_->bb_max, tmin, tmax)) {
_raycollision(_node->right_child_, _data);
}
}
}
//=============================================================================
\ No newline at end of file
//=============================================================================
//
// OpenFlipper
// Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
// www.openflipper.org
//
//-----------------------------------------------------------------------------
//
// License
//
// OpenFlipper is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenFlipper 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
// $Revision: 1720 $
// $Author: moebius $
// $Date: 2008-05-09 14:15:53 +0200 (Fri, 09 May 2008) $
//
//=============================================================================
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision: 10745 $ *
* $LastChangedBy: moebius $ *
* $Date: 2011-01-26 10:23:50 +0100 (Wed, 26 Jan 2011) $ *
* *
\*===========================================================================*/
......@@ -49,6 +60,7 @@
//== CLASS DEFINITION =========================================================
#include <vector>
template <class BSPCore>
......@@ -79,11 +91,22 @@ public: //---------------------------------------------------------------------
Handle handle;
Scalar dist;
};
/// Store nearest neighbor information
struct RayCollision
{
RayCollision() {}
RayCollision(Handle _h, Scalar _d, std::vector<Handle> _v) : handle(_h), dist(_d), hit_vertices(_v) {}
Handle handle;
Scalar dist;
std::vector<Handle> hit_vertices;
};
/// Return handle of the nearest neighbor
/// Return handle of the nearest neighbor face
NearestNeighbor nearest(const Point& _p) const;
/// Return handles of all hit collided faces, and the handle of the nearest collided face
RayCollision raycollision (const Point& _p, const Point& _r) const;
private: //---------------------------------------------------------------------
......@@ -96,10 +119,23 @@ private: //---------------------------------------------------------------------
Scalar dist;
Handle nearest;
};
/// Store ray collide information
struct RayCollisionData
{
Point ref;
Point ray;
Scalar dist;
Handle nearest;
std::vector<Handle> hit_vertices;
};
// Recursive part of nearest()
void _nearest(Node* _node, NearestNeighborData& _data) const;
//resursive part of raycollide()
void _raycollision(Node* _node, RayCollisionData& _data) const;
};
......
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision: 10745 $ *
* $LastChangedBy: moebius $ *
* $Date: 2011-01-26 10:23:50 +0100 (Wed, 26 Jan 2011) $ *
* *
\*===========================================================================*/
//=============================================================================
//
// CLASS TreeNode
//
//=============================================================================
#ifndef MB_BSPTREENODE_HH
#define MB_BSPTREENODE_HH
//== INCLUDES =================================================================
#include <ACG/Geometry/Types/PlaneT.hh>
#include <ACG/Geometry/Algorithms.hh>
#include <ObjectTypes/PolyMesh/PolyMeshTypes.hh>
//== CLASS DEFINITION =========================================================
// Node of the tree: contains parent, children and splitting plane
template <class Mesh>
struct TreeNode
{
typedef typename Mesh::FaceHandle Handle;
typedef typename Mesh::Point Point;
typedef typename Mesh::VertexHandle VertexHandle;
typedef std::vector<Handle> Handles;
typedef typename Handles::iterator HandleIter;
typedef typename Point::value_type Scalar;
typedef ACG::Geometry::PlaneT<Scalar> Plane;
TreeNode(const Handles& _handles, TreeNode* _parent)
: handles_(_handles),
parent_(_parent), left_child_(0), right_child_(0) {}
~TreeNode()
{
delete left_child_;
delete right_child_;
if (parent_)
{
if (this == parent_->left_child_)
parent_->left_child_ = 0;
else
parent_->right_child_ = 0;
}
}
HandleIter begin() {
return handles_.begin();
}
HandleIter end() {
return handles_.end();
}
Handles handles_;
TreeNode *parent_, *left_child_, *right_child_;
Plane plane_;
Point bb_min, bb_max;
/// This visualizes the bounding boxes
void visualizeTree(PolyMesh *_object, int _max_depth)
{
if (_max_depth > 0 && (left_child_ || right_child_) )
{
if (left_child_)
left_child_->visualizeTree(_object, _max_depth-1);
if (right_child_)
right_child_->visualizeTree(_object, _max_depth-1);
}
else
{
Point size_ = bb_max - bb_min;
std::vector<VertexHandle> vhandle(8);
vhandle[0] = _object->add_vertex(bb_min+Point(0.0,0.0,size_[2]));
vhandle[1] = _object->add_vertex(bb_min+Point(size_[0],0.0,size_[2]));
vhandle[2] = _object->add_vertex(bb_min+Point(size_[0],size_[1],size_[2]));
vhandle[3] = _object->add_vertex(bb_min+Point(0.0,size_[1],size_[2]));
vhandle[4] = _object->add_vertex(bb_min+Point(0.0,0.0,0.0));
vhandle[5] = _object->add_vertex(bb_min+Point(size_[0],0.0,0.0));
vhandle[6] = _object->add_vertex(bb_min+Point(size_[0],size_[1],0.0));
vhandle[7] = _object->add_vertex(bb_min+Point(0.0,size_[1],0.0));
// generate (quadrilateral) faces
std::vector<VertexHandle> face_vhandles;
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[3]);
_object->add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[7]);
face_vhandles.push_back(vhandle[6]);
face_vhandles.push_back(vhandle[5]);
face_vhandles.push_back(vhandle[4]);
_object->add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[4]);
face_vhandles.push_back(vhandle[5]);
_object->add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[5]);
face_vhandles.push_back(vhandle[6]);
_object->add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[6]);
face_vhandles.push_back(vhandle[7]);
_object->add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[7]);
face_vhandles.push_back(vhandle[4]);
_object->add_face(face_vhandles);
}
}
};
//=============================================================================
#endif // MB_BSPTREENODE_HH defined
//=============================================================================
//=============================================================================
//
// OpenFlipper
// Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
// www.openflipper.org
//
//-----------------------------------------------------------------------------
//
// License
//
// OpenFlipper is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenFlipper 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
// $Revision: 1720 $
// $Author: moebius $
// $Date: 2008-05-09 14:15:53 +0200 (Fri, 09 May 2008) $
//
//=============================================================================
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision: 12862 $ *
* $LastChangedBy: moebius $ *
* $Date: 2011-11-16 14:25:59 +0100 (Wed, 16 Nov 2011) $ *
* *
\*===========================================================================*/
......@@ -48,38 +59,6 @@
//== CLASS DEFINITION =========================================================
template <class BSPTraits>
TriangleBSPCoreT<BSPTraits>::Node::
Node(const Handles& _handles, Node* _parent)
: handles_(_handles),
parent_(_parent), left_child_(0), right_child_(0)
{}
//-----------------------------------------------------------------------------
template <class BSPTraits>
TriangleBSPCoreT<BSPTraits>::Node::
~Node()
{
delete left_child_;
delete right_child_;
if (parent_)
{
if (this == parent_->left_child_)
parent_->left_child_ = 0;
else
parent_->right_child_ = 0;
}
}
//-----------------------------------------------------------------------------
template <class BSPTraits>
void
TriangleBSPCoreT<BSPTraits>::
......@@ -92,8 +71,11 @@ build(unsigned int _max_handles, unsigned int _max_depth)
// delete own handles (don't store them twice)
handles_ = Handles();
nodes=1;
traits_.calculateBoundingBoxRoot (root_);
// call recursive helper
_build(root_, _max_handles, _max_depth);
}
......@@ -110,44 +92,23 @@ _build(Node* _node,
// should we stop at this level ?
if ((_depth == 0) || ((_node->end()-_node->begin()) <= (int)_max_handles))
return;
// compute bounding box
HandleIter it;
Point p0, p1, p2;
Point bb_min; bb_min.vectorize(FLT_MAX);
Point bb_max; bb_max.vectorize(-FLT_MAX);
for (it=_node->begin(); it!=_node->end(); ++it)
{
traits_.points(*it, p0, p1, p2);
bb_min.minimize(p0);
bb_min.minimize(p1);
bb_min.minimize(p2);
bb_max.maximize(p0);
bb_max.maximize(p1);
bb_max.maximize(p2);
}
// split longest side of bounding box