Commit ec397df2 authored by Joseph Mirabel's avatar Joseph Mirabel
Browse files

[BVH] Split BVHModel into two classes.

parent 1658cc0f
......@@ -54,11 +54,9 @@ namespace fcl
class ConvexBase;
/// @brief A class describing the bounding hierarchy of a mesh model or a point cloud model (which is viewed as a degraded version of mesh)
template<typename BV>
class BVHModel : public CollisionGeometry
/// @brief A base class describing the bounding hierarchy of a mesh model or a point cloud model (which is viewed as a degraded version of mesh)
class BVHModelBase : public CollisionGeometry
{
public:
/// @brief Geometry point data
Vec3f* vertices;
......@@ -78,12 +76,6 @@ public:
/// @brief The state of BVH building process
BVHBuildState build_state;
/// @brief Split rule to split one BV node into two children
boost::shared_ptr<BVSplitterBase<BV> > bv_splitter;
/// @brief Fitting rule to fit a BV node to a set of geometry primitives
boost::shared_ptr<BVFitterBase<BV> > bv_fitter;
/// @brief Convex<Triangle> representation of this object
boost::shared_ptr< ConvexBase > convex;
......@@ -99,66 +91,32 @@ public:
}
/// @brief Constructing an empty BVH
BVHModel() : vertices(NULL),
tri_indices(NULL),
prev_vertices(NULL),
num_tris(0),
num_vertices(0),
build_state(BVH_BUILD_STATE_EMPTY),
bv_splitter(new BVSplitter<BV>(SPLIT_METHOD_MEAN)),
bv_fitter(new BVFitter<BV>()),
num_tris_allocated(0),
num_vertices_allocated(0),
num_bvs_allocated(0),
num_vertex_updated(0),
primitive_indices(NULL),
bvs(NULL),
num_bvs(0)
BVHModelBase() : vertices(NULL),
tri_indices(NULL),
prev_vertices(NULL),
num_tris(0),
num_vertices(0),
build_state(BVH_BUILD_STATE_EMPTY),
num_tris_allocated(0),
num_vertices_allocated(0),
num_vertex_updated(0)
{
}
/// @brief copy from another BVH
BVHModel(const BVHModel& other);
BVHModelBase(const BVHModelBase& other);
/// @brief deconstruction, delete mesh data related.
~BVHModel()
virtual ~BVHModelBase ()
{
delete [] vertices;
delete [] tri_indices;
delete [] bvs;
delete [] prev_vertices;
delete [] primitive_indices;
}
/// @brief We provide getBV() and getNumBVs() because BVH may be compressed (in future), so we must provide some flexibility here
/// @brief Access the bv giving the its index
const BVNode<BV>& getBV(int id) const
{
assert (id < num_bvs);
return bvs[id];
}
/// @brief Access the bv giving the its index
BVNode<BV>& getBV(int id)
{
assert (id < num_bvs);
return bvs[id];
}
/// @brief Get the number of bv in the BVH
int getNumBVs() const
{
return num_bvs;
}
/// @brief Get the object type: it is a BVH
OBJECT_TYPE getObjectType() const { return OT_BVH; }
/// @brief Get the BV type: default is unknown
NODE_TYPE getNodeType() const { return BV_UNKNOWN; }
/// @brief Compute the AABB for the BVH, used for broad-phase collision
void computeLocalAABB();
......@@ -211,21 +169,16 @@ public:
/// @brief End BVH model update, will also refit or rebuild the bounding volume hierarchy
int endUpdateModel(bool refit = true, bool bottomup = true);
/// @brief Check the number of memory used
int memUsage(int msg) const;
/// @brief Build this Convex<Triangle> representation of this model.
/// \note this only takes the points of this model. It does not check that the
/// object is convex. It does not compute a convex hull.
void buildConvexRepresentation();
void buildConvexRepresentation(bool share_memory);
virtual int memUsage(int msg) const = 0;
/// @brief This is a special acceleration: BVH_model default stores the BV's transform in world coordinate. However, we can also store each BV's transform related to its parent
/// BV node. When traversing the BVH, this can save one matrix transformation.
void makeParentRelative()
{
Matrix3f I (Matrix3f::Identity());
makeParentRelativeRecurse(0, I, Vec3f());
}
virtual void makeParentRelative() = 0;
Vec3f computeCOM() const
{
......@@ -277,12 +230,95 @@ public:
return C.trace() * Matrix3f::Identity() - C;
}
private:
protected:
virtual void deleteBVs() = 0;
virtual bool allocateBVs() = 0;
/// @brief Build the bounding volume hierarchy
virtual int buildTree() = 0;
/// @brief Refit the bounding volume hierarchy
virtual int refitTree(bool bottomup) = 0;
int num_tris_allocated;
int num_vertices_allocated;
int num_bvs_allocated;
int num_vertex_updated; /// for ccd vertex update
};
/// @brief A class describing the bounding hierarchy of a mesh model or a point cloud model (which is viewed as a degraded version of mesh)
template<typename BV>
class BVHModel : public BVHModelBase
{
public:
/// @brief Split rule to split one BV node into two children
boost::shared_ptr<BVSplitterBase<BV> > bv_splitter;
/// @brief Fitting rule to fit a BV node to a set of geometry primitives
boost::shared_ptr<BVFitterBase<BV> > bv_fitter;
/// @brief Constructing an empty BVH
BVHModel() : BVHModelBase (),
bv_splitter(new BVSplitter<BV>(SPLIT_METHOD_MEAN)),
bv_fitter(new BVFitter<BV>()),
num_bvs_allocated(0),
primitive_indices(NULL),
bvs(NULL),
num_bvs(0)
{
}
/// @brief copy from another BVH
BVHModel(const BVHModel& other);
/// @brief deconstruction, delete mesh data related.
~BVHModel()
{
delete [] bvs;
delete [] primitive_indices;
}
/// @brief We provide getBV() and getNumBVs() because BVH may be compressed (in future), so we must provide some flexibility here
/// @brief Access the bv giving the its index
const BVNode<BV>& getBV(int id) const
{
assert (id < num_bvs);
return bvs[id];
}
/// @brief Access the bv giving the its index
BVNode<BV>& getBV(int id)
{
assert (id < num_bvs);
return bvs[id];
}
/// @brief Get the number of bv in the BVH
int getNumBVs() const
{
return num_bvs;
}
/// @brief Get the BV type: default is unknown
NODE_TYPE getNodeType() const { return BV_UNKNOWN; }
/// @brief Check the number of memory used
int memUsage(int msg) const;
/// @brief This is a special acceleration: BVH_model default stores the BV's transform in world coordinate. However, we can also store each BV's transform related to its parent
/// BV node. When traversing the BVH, this can save one matrix transformation.
void makeParentRelative()
{
Matrix3f I (Matrix3f::Identity());
makeParentRelativeRecurse(0, I, Vec3f());
}
private:
void deleteBVs();
bool allocateBVs();
int num_bvs_allocated;
unsigned int* primitive_indices;
/// @brief Bounding volume hierarchy
......
......@@ -51,6 +51,9 @@ namespace fcl {
class Transform3f;
class AABB;
class BVHModelBase;
typedef boost::shared_ptr<BVHModelBase> BVHModelPtr_t;
}
} // namespace hpp
......
......@@ -46,15 +46,13 @@ namespace hpp
namespace fcl
{
template<typename BV>
BVHModel<BV>::BVHModel(const BVHModel<BV>& other) : CollisionGeometry(other),
num_tris(other.num_tris),
num_vertices(other.num_vertices),
build_state(other.build_state),
bv_splitter(other.bv_splitter),
bv_fitter(other.bv_fitter),
num_tris_allocated(other.num_tris),
num_vertices_allocated(other.num_vertices)
BVHModelBase::BVHModelBase(const BVHModelBase& other) :
CollisionGeometry(other),
num_tris(other.num_tris),
num_vertices(other.num_vertices),
build_state(other.build_state),
num_tris_allocated(other.num_tris),
num_vertices_allocated(other.num_vertices)
{
if(other.vertices)
{
......@@ -79,7 +77,20 @@ BVHModel<BV>::BVHModel(const BVHModel<BV>& other) : CollisionGeometry(other),
}
else
prev_vertices = NULL;
}
void BVHModelBase::buildConvexRepresentation(bool share_memory)
{
if (!convex) {
convex.reset(new Convex<Triangle>(!share_memory, vertices, num_vertices, tri_indices, num_vertices));
}
}
template<typename BV>
BVHModel<BV>::BVHModel(const BVHModel<BV>& other) : BVHModelBase(other),
bv_splitter(other.bv_splitter),
bv_fitter(other.bv_fitter)
{
if(other.primitive_indices)
{
int num_primitives = 0;
......@@ -112,18 +123,16 @@ BVHModel<BV>::BVHModel(const BVHModel<BV>& other) : CollisionGeometry(other),
}
template<typename BV>
int BVHModel<BV>::beginModel(int num_tris_, int num_vertices_)
int BVHModelBase::beginModel(int num_tris_, int num_vertices_)
{
if(build_state != BVH_BUILD_STATE_EMPTY)
{
delete [] vertices; vertices = NULL;
delete [] tri_indices; tri_indices = NULL;
delete [] bvs; bvs = NULL;
delete [] prev_vertices; prev_vertices = NULL;
delete [] primitive_indices; primitive_indices = NULL;
num_vertices_allocated = num_vertices = num_tris_allocated = num_tris = num_bvs_allocated = num_bvs = 0;
num_vertices_allocated = num_vertices = num_tris_allocated = num_tris = 0;
deleteBVs();
}
if(num_tris_ <= 0) num_tris_ = 8;
......@@ -158,9 +167,7 @@ int BVHModel<BV>::beginModel(int num_tris_, int num_vertices_)
return BVH_OK;
}
template<typename BV>
int BVHModel<BV>::addVertex(const Vec3f& p)
int BVHModelBase::addVertex(const Vec3f& p)
{
if(build_state != BVH_BUILD_STATE_BEGUN)
{
......@@ -189,8 +196,7 @@ int BVHModel<BV>::addVertex(const Vec3f& p)
return BVH_OK;
}
template<typename BV>
int BVHModel<BV>::addTriangle(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3)
int BVHModelBase::addTriangle(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3)
{
if(build_state == BVH_BUILD_STATE_PROCESSED)
{
......@@ -243,8 +249,7 @@ int BVHModel<BV>::addTriangle(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3)
return BVH_OK;
}
template<typename BV>
int BVHModel<BV>::addSubModel(const std::vector<Vec3f>& ps)
int BVHModelBase::addSubModel(const std::vector<Vec3f>& ps)
{
if(build_state == BVH_BUILD_STATE_PROCESSED)
{
......@@ -278,8 +283,7 @@ int BVHModel<BV>::addSubModel(const std::vector<Vec3f>& ps)
return BVH_OK;
}
template<typename BV>
int BVHModel<BV>::addSubModel(const std::vector<Vec3f>& ps, const std::vector<Triangle>& ts)
int BVHModelBase::addSubModel(const std::vector<Vec3f>& ps, const std::vector<Triangle>& ts)
{
if(build_state == BVH_BUILD_STATE_PROCESSED)
{
......@@ -340,8 +344,7 @@ int BVHModel<BV>::addSubModel(const std::vector<Vec3f>& ps, const std::vector<Tr
return BVH_OK;
}
template<typename BV>
int BVHModel<BV>::endModel()
int BVHModelBase::endModel()
{
if(build_state != BVH_BUILD_STATE_BEGUN)
{
......@@ -383,24 +386,9 @@ int BVHModel<BV>::endModel()
num_vertices_allocated = num_vertices;
}
// construct BVH tree
int num_bvs_to_be_allocated = 0;
if(num_tris == 0)
num_bvs_to_be_allocated = 2 * num_vertices - 1;
else
num_bvs_to_be_allocated = 2 * num_tris - 1;
bvs = new BVNode<BV> [num_bvs_to_be_allocated];
primitive_indices = new unsigned int [num_bvs_to_be_allocated];
if(!bvs || !primitive_indices)
{
std::cerr << "BVH Error! Out of memory for BV array in endModel()!" << std::endl;
if (!allocateBVs ())
return BVH_ERR_MODEL_OUT_OF_MEMORY;
}
num_bvs_allocated = num_bvs_to_be_allocated;
num_bvs = 0;
buildTree();
......@@ -412,8 +400,7 @@ int BVHModel<BV>::endModel()
template<typename BV>
int BVHModel<BV>::beginReplaceModel()
int BVHModelBase::beginReplaceModel()
{
if(build_state != BVH_BUILD_STATE_PROCESSED)
{
......@@ -430,8 +417,7 @@ int BVHModel<BV>::beginReplaceModel()
return BVH_OK;
}
template<typename BV>
int BVHModel<BV>::replaceVertex(const Vec3f& p)
int BVHModelBase::replaceVertex(const Vec3f& p)
{
if(build_state != BVH_BUILD_STATE_REPLACE_BEGUN)
{
......@@ -445,8 +431,7 @@ int BVHModel<BV>::replaceVertex(const Vec3f& p)
return BVH_OK;
}
template<typename BV>
int BVHModel<BV>::replaceTriangle(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3)
int BVHModelBase::replaceTriangle(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3)
{
if(build_state != BVH_BUILD_STATE_REPLACE_BEGUN)
{
......@@ -460,8 +445,7 @@ int BVHModel<BV>::replaceTriangle(const Vec3f& p1, const Vec3f& p2, const Vec3f&
return BVH_OK;
}
template<typename BV>
int BVHModel<BV>::replaceSubModel(const std::vector<Vec3f>& ps)
int BVHModelBase::replaceSubModel(const std::vector<Vec3f>& ps)
{
if(build_state != BVH_BUILD_STATE_REPLACE_BEGUN)
{
......@@ -477,8 +461,7 @@ int BVHModel<BV>::replaceSubModel(const std::vector<Vec3f>& ps)
return BVH_OK;
}
template<typename BV>
int BVHModel<BV>::endReplaceModel(bool refit, bool bottomup)
int BVHModelBase::endReplaceModel(bool refit, bool bottomup)
{
if(build_state != BVH_BUILD_STATE_REPLACE_BEGUN)
{
......@@ -510,8 +493,7 @@ int BVHModel<BV>::endReplaceModel(bool refit, bool bottomup)
template<typename BV>
int BVHModel<BV>::beginUpdateModel()
int BVHModelBase::beginUpdateModel()
{
if(build_state != BVH_BUILD_STATE_PROCESSED && build_state != BVH_BUILD_STATE_UPDATED)
{
......@@ -538,8 +520,7 @@ int BVHModel<BV>::beginUpdateModel()
return BVH_OK;
}
template<typename BV>
int BVHModel<BV>::updateVertex(const Vec3f& p)
int BVHModelBase::updateVertex(const Vec3f& p)
{
if(build_state != BVH_BUILD_STATE_UPDATE_BEGUN)
{
......@@ -553,8 +534,7 @@ int BVHModel<BV>::updateVertex(const Vec3f& p)
return BVH_OK;
}
template<typename BV>
int BVHModel<BV>::updateTriangle(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3)
int BVHModelBase::updateTriangle(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3)
{
if(build_state != BVH_BUILD_STATE_UPDATE_BEGUN)
{
......@@ -568,8 +548,7 @@ int BVHModel<BV>::updateTriangle(const Vec3f& p1, const Vec3f& p2, const Vec3f&
return BVH_OK;
}
template<typename BV>
int BVHModel<BV>::updateSubModel(const std::vector<Vec3f>& ps)
int BVHModelBase::updateSubModel(const std::vector<Vec3f>& ps)
{
if(build_state != BVH_BUILD_STATE_UPDATE_BEGUN)
{
......@@ -585,8 +564,7 @@ int BVHModel<BV>::updateSubModel(const std::vector<Vec3f>& ps)
return BVH_OK;
}
template<typename BV>
int BVHModel<BV>::endUpdateModel(bool refit, bool bottomup)
int BVHModelBase::endUpdateModel(bool refit, bool bottomup)
{
if(build_state != BVH_BUILD_STATE_UPDATE_BEGUN)
{
......@@ -621,6 +599,58 @@ int BVHModel<BV>::endUpdateModel(bool refit, bool bottomup)
void BVHModelBase::computeLocalAABB()
{
AABB aabb_;
for(int i = 0; i < num_vertices; ++i)
{
aabb_ += vertices[i];
}
aabb_center = aabb_.center();
aabb_radius = 0;
for(int i = 0; i < num_vertices; ++i)
{
FCL_REAL r = (aabb_center - vertices[i]).squaredNorm();
if(r > aabb_radius) aabb_radius = r;
}
aabb_radius = sqrt(aabb_radius);
aabb_local = aabb_;
}
template<typename BV>
void BVHModel<BV>::deleteBVs()
{
delete [] bvs; bvs = NULL;
delete [] primitive_indices; primitive_indices = NULL;
num_bvs_allocated = num_bvs = 0;
}
template<typename BV>
bool BVHModel<BV>::allocateBVs()
{
// construct BVH tree
int num_bvs_to_be_allocated = 0;
if(num_tris == 0)
num_bvs_to_be_allocated = 2 * num_vertices - 1;
else
num_bvs_to_be_allocated = 2 * num_tris - 1;
bvs = new BVNode<BV> [num_bvs_to_be_allocated];
primitive_indices = new unsigned int [num_bvs_to_be_allocated];
if(!bvs || !primitive_indices)
{
std::cerr << "BVH Error! Out of memory for BV array in endModel()!" << std::endl;
return false;
}
num_bvs_allocated = num_bvs_to_be_allocated;
num_bvs = 0;
return true;
}
template<typename BV>
int BVHModel<BV>::memUsage(int msg) const
......@@ -642,14 +672,6 @@ int BVHModel<BV>::memUsage(int msg) const
return BVH_OK;
}
template<typename BV>
void BVHModel<BV>::buildConvexRepresentation()
{
if (!convex) {
convex.reset(new Convex<Triangle>(false, vertices, num_vertices, tri_indices, num_vertices));
}
}
template<typename BV>
int BVHModel<BV>::buildTree()
{
......@@ -874,29 +896,6 @@ int BVHModel<BV>::refitTree_topdown()
return BVH_OK;
}
template<typename BV>
void BVHModel<BV>::computeLocalAABB()
{
AABB aabb_;
for(int i = 0; i < num_vertices; ++i)
{
aabb_ += vertices[i];
}
aabb_center = aabb_.center();
aabb_radius = 0;
for(int i = 0; i < num_vertices; ++i)
{
FCL_REAL r = (aabb_center - vertices[i]).squaredNorm();
if(r > aabb_radius) aabb_radius = r;
}
aabb_radius = sqrt(aabb_radius);
aabb_local = aabb_;
}
template<>
void BVHModel<OBB>::makeParentRelativeRecurse(int bv_id, Matrix3f& parent_axes, const Vec3f& parent_c)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment