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

Moved BSP Tree from PhySim here.

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@14113 383ad7c9-94d9-4d36-a494-682f7c89f535
parent ebae0c23
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Config
#==============================================================================
SUBDIRS = $(call find-subdirs)
PACKAGES := qt glut glew opengl x11 math ACG2 openmesh2
PROJ_LIBS =
MODULES := moc cxx
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Rules
#==============================================================================
//=============================================================================
//
// 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) $
//
//=============================================================================
//=============================================================================
//
// CLASS BSPImplT
//
//=============================================================================
#define BSPIMPLT_C
//== INCLUDES =================================================================
#include "BSPImplT.hh"
#include <float.h>
//== CLASS DEFINITION =========================================================
template <class BSPCore>
typename BSPImplT<BSPCore>::NearestNeighbor
BSPImplT<BSPCore>::
nearest(const Point& _p) const
{
NearestNeighborData data;
data.ref = _p;
data.dist = FLT_MAX;
_nearest(this->root_, data);
return NearestNeighbor(data.nearest, sqrt(data.dist));
}
//-----------------------------------------------------------------------------
template <class BSPCore>
void
BSPImplT<BSPCore>::
_nearest(Node* _node, NearestNeighborData& _data) const
{
// terminal node
if (!_node->left_child_)
{
Scalar dist;
for (HandleIter it=_node->begin(); it!=_node->end(); ++it)
{
dist = this->traits_.sqrdist(*it, _data.ref);
if (dist < _data.dist)
{
_data.dist = dist;
_data.nearest = *it;
}
}
}
// non-terminal node
else
{
Scalar dist = _node->plane_.distance(_data.ref);
if (dist > 0.0)
{
_nearest(_node->left_child_, _data);
if (dist*dist < _data.dist)
_nearest(_node->right_child_, _data);
}
else
{
_nearest(_node->right_child_, _data);
if (dist*dist < _data.dist)
_nearest(_node->left_child_, _data);
}
}
}
//=============================================================================
//=============================================================================
//
// 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) $
//
//=============================================================================
//=============================================================================
//
// CLASS BSPImplT
//
//=============================================================================
#ifndef BSPIMPLT_HH
#define BSPIMPLT_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/Geometry/VectorT.hh>
//== CLASS DEFINITION =========================================================
template <class BSPCore>
class BSPImplT : public BSPCore
{
public: //---------------------------------------------------------------------
typedef typename BSPCore::Traits Traits;
typedef typename BSPCore::Handle Handle;
typedef typename BSPCore::Point Point;
typedef typename BSPCore::Scalar Scalar;
typedef typename BSPCore::Node Node;
typedef typename BSPCore::Handles Handles;
typedef typename BSPCore::HandleIter HandleIter;
public: //---------------------------------------------------------------------
BSPImplT(const Traits& _traits) : BSPCore(_traits) {}
~BSPImplT() {}
/// Store nearest neighbor information
struct NearestNeighbor
{
NearestNeighbor() {}
NearestNeighbor(Handle _h, Scalar _d) : handle(_h), dist(_d) {}
Handle handle;
Scalar dist;
};
/// Return handle of the nearest neighbor
NearestNeighbor nearest(const Point& _p) const;
private: //---------------------------------------------------------------------
/// Store nearest neighbor information
struct NearestNeighborData
{
Point ref;
Scalar dist;
Handle nearest;
};
// Recursive part of nearest()
void _nearest(Node* _node, NearestNeighborData& _data) const;
};
//=============================================================================
#if defined(OM_INCLUDE_TEMPLATES) && !defined(BSPIMPLT_C)
# define BSPIMPLT_TEMPLATES
# include "BSPImplT.cc"
#endif
//=============================================================================
#endif // BSPIMPLT_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) $
//
//=============================================================================
//=============================================================================
//
// CLASS TriangleBSPCoreT
//
//=============================================================================
#define TRIANGLEBSPCORET_C
//== INCLUDES =================================================================
#include "TriangleBSPCoreT.hh"
//== 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>::
build(unsigned int _max_handles, unsigned int _max_depth)
{
// init
delete root_;
root_ = new Node(handles_, 0);
// delete own handles (don't store them twice)
handles_ = Handles();
// call recursive helper
_build(root_, _max_handles, _max_depth);
}
//-----------------------------------------------------------------------------
template <class BSPTraits>
void
TriangleBSPCoreT<BSPTraits>::
_build(Node* _node,
unsigned int _max_handles,
unsigned int _depth)
{
// 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
Point bb = bb_max - bb_min;
Scalar length = bb[0];
int axis = 0;
if (bb[1] > length) length = bb[ (axis=1) ];
if (bb[2] > length) length = bb[ (axis=2) ];
// construct splitting plane
const Point XYZ[3] = { Point(1,0,0), Point(0,1,0), Point(0,0,1) };
_node->plane_ = Plane((bb_min+bb_max)*0.5, XYZ[axis]);
// partition for left and right child
Handles lhandles, rhandles;
lhandles.reserve(_node->handles_.size()/2);
rhandles.reserve(_node->handles_.size()/2);
bool left, right;
for (it=_node->begin(); it!=_node->end(); ++it)
{
traits_.points(*it, p0, p1, p2);
left = right = false;
if (_node->plane_(p0)) left = true;
else right = true;
if (_node->plane_(p1)) left = true;
else right = true;
if (_node->plane_(p2)) left = true;
else right = true;
if (left) lhandles.push_back(*it);
if (right) rhandles.push_back(*it);
}
// check it
if (lhandles.size() == _node->handles_.size() ||
rhandles.size() == _node->handles_.size())
return;
else
_node->handles_ = Handles();
// create children
_node->left_child_ = new Node(lhandles, _node); lhandles = Handles();
_node->right_child_ = new Node(rhandles, _node); rhandles = Handles();
// recurse to childen
_build(_node->left_child_, _max_handles, _depth-1);
_build(_node->right_child_, _max_handles, _depth-1);
}
//=============================================================================
//=============================================================================
//
// 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) $
//
//=============================================================================
//=============================================================================
//
// CLASS TriangleBSPCoreT
//
//=============================================================================
#ifndef TRIANGLEBSPCORET_HH
#define TRIANGLEBSPCORET_HH
//== INCLUDES =================================================================
#include <ACG/Geometry/Types/PlaneT.hh>
#include <OpenMesh/Core/Geometry/VectorT.hh>
#include <vector>
//== CLASS DEFINITION =========================================================
template <class BSPTraits>
class TriangleBSPCoreT
{
public: //---------------------------------------------------------------------
typedef BSPTraits Traits;
typedef typename BSPTraits::Point Point;
typedef typename BSPTraits::Handle Handle;
typedef typename Point::value_type Scalar;
typedef ACG::Geometry::PlaneT<Scalar> Plane;
typedef std::vector<Handle> Handles;
typedef typename Handles::iterator HandleIter;
public: //---------------------------------------------------------------------
/** Constructor: need traits that define the types and
give us the points by traits_.point(PointHandle) */
TriangleBSPCoreT(const BSPTraits& _traits) : traits_(_traits), root_(0) {}
/// Destructor
~TriangleBSPCoreT() { delete root_; }
/// Reserve memory for _n entries
void reserve(unsigned int _n) { handles_.reserve(_n); }
/// Add a handle to the BSP
void push_back(Handle _h) { handles_.push_back(_h); }
/// Finally build the tree
void build(unsigned int _max_handles, unsigned int _max_depth);
protected: //-------------------------------------------------------------------
// Node of the tree: contains parent, children and splitting plane
struct Node
{
Node(const Handles& _handles, Node* _parent);
~Node();
HandleIter begin() { return handles_.begin(); }
HandleIter end() { return handles_.end(); }
Handles handles_;
Node *parent_, *left_child_, *right_child_;
Plane plane_;
};
private: //---------------------------------------------------------------------
// Recursive part of build()
void _build(Node* _node,
unsigned int _max_handles,
unsigned int _depth);
protected: //-------------------------------------------------------------------
BSPTraits traits_;
Handles handles_;
Node* root_;
};
//=============================================================================
#if defined(OM_INCLUDE_TEMPLATES) && !defined(TRIANGLEBSPCORET_C)
# define TRIANGLEBSPCORET_TEMPLATES
# include "TriangleBSPCoreT.cc"
#endif
//=============================================================================
#endif // TRIANGLEBSPCORET_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) $
//
//=============================================================================
//=============================================================================
//
// CLASS TriangleBSPT
//
//=============================================================================
#ifndef MB_TRIANGLEBSP_HH
#define MB_TRIANGLEBSP_HH
//== INCLUDES =================================================================
#include "TriangleBSPCoreT.hh"
#include "BSPImplT.hh"
//#include "Distance.hh"
#include <ACG/Geometry/Algorithms.hh>