First Commit.

This commit is contained in:
Marco Di Benedetto 2005-09-26 18:33:16 +00:00
parent 8e50d54365
commit fefa8ab4c3
7 changed files with 1255 additions and 0 deletions

View File

@ -0,0 +1,408 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
****************************************************************************/
#ifndef __VCGLIB_AABBBINARYTREE_TYPE_H
#define __VCGLIB_AABBBINARYTREE_TYPE_H
// standard headers
#include <assert.h>
// stl headers
#include <vector>
// vcg headers
#include <vcg/space/point3.h>
#include <vcg/space/box3.h>
/***************************************************************************************/
namespace vcg {
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
class AABBBinaryTree {
public:
typedef AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE> ClassType;
typedef OBJTYPE ObjType;
typedef ObjType * ObjPtr;
typedef SCALARTYPE ScalarType;
typedef NODEAUXDATATYPE NodeAuxDataType;
typedef Point3<ScalarType> CoordType;
typedef std::vector<ObjPtr> ObjPtrVector;
typedef typename ObjPtrVector::iterator ObjPtrVectorIterator;
typedef typename ObjPtrVector::const_iterator ObjPtrVectorConstIterator;
public:
class AABBBinaryTreeNode {
public:
AABBBinaryTreeNode * parent;
AABBBinaryTreeNode * children[2];
CoordType boxCenter;
CoordType boxHalfDims;
ObjPtrVectorIterator oBegin;
ObjPtrVectorIterator oEnd;
unsigned char splitAxis;
NodeAuxDataType auxData;
inline AABBBinaryTreeNode(AABBBinaryTreeNode * pParent = 0);
inline ~AABBBinaryTreeNode(void);
inline void Clear(void);
inline bool IsLeaf(void) const;
inline unsigned int ObjectsCount(void) const;
inline unsigned int & Flags(void);
inline const unsigned int & Flags(void) const;
inline ScalarType & ScalarValue(void);
inline const ScalarType & ScalarValue(void) const;
inline int & IntValue(void);
inline const int & IntValue(void) const;
inline unsigned int & UIntValue(void);
inline const unsigned int & UIntValue(void) const;
inline void * & PtrValue(void);
inline const void * & PtrValue(void) const;
protected:
union SharedDataUnion {
unsigned int flags;
int intValue;
unsigned int uintValue;
ScalarType scalarValue;
void * ptrValue;
};
SharedDataUnion sharedData;
};
typedef AABBBinaryTreeNode NodeType;
ObjPtrVector pObjects;
NodeType * pRoot;
inline AABBBinaryTree(void);
inline ~AABBBinaryTree(void);
inline void Clear(void);
template <class OBJITERATOR, class OBJITERATORPTRFUNCT, class OBJBOXFUNCT, class OBJBARYCENTERFUNCT>
inline bool Set(const OBJITERATOR & oBegin, const OBJITERATOR & oEnd, OBJITERATORPTRFUNCT & objPtr, OBJBOXFUNCT & objBox, OBJBARYCENTERFUNCT & objBarycenter, const unsigned int maxElemsPerLeaf = 1, const ScalarType & leafBoxMaxVolume = ((ScalarType)0), const bool useVariance = true);
protected:
template <class OBJBOXFUNCT, class OBJBARYCENTERFUNCT>
inline static NodeType * BoundObjects(NodeType * parent, const ObjPtrVectorIterator & oBegin, const ObjPtrVectorIterator & oEnd, const unsigned int size, const unsigned int maxElemsPerLeaf, const ScalarType & leafBoxMaxVolume, const bool useVariance, OBJBOXFUNCT & getBox, OBJBARYCENTERFUNCT & getBarycenter);
template <class OBJBARYCENTERFUNCT>
inline static int BalanceMedian(const ObjPtrVectorIterator & oBegin, const ObjPtrVectorIterator & oEnd, const int size, const int splitAxis, OBJBARYCENTERFUNCT & getBarycenter, ObjPtrVectorIterator & medianIter);
};
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTree(void) {
this->pObjects.clear();
this->pRoot = 0;
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::~AABBBinaryTree(void) {
this->pObjects.clear();
delete this->pRoot;
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
void AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::Clear(void) {
this->pObjects.clear();
delete this->pRoot;
this->pRoot = 0;
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
template <class OBJITERATOR, class OBJITERATORPTRFUNCT, class OBJBOXFUNCT, class OBJBARYCENTERFUNCT>
bool AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::Set(const OBJITERATOR & oBegin, const OBJITERATOR & oEnd, OBJITERATORPTRFUNCT & objPtr, OBJBOXFUNCT & objBox, OBJBARYCENTERFUNCT & objBarycenter, const unsigned int maxElemsPerLeaf, const ScalarType & leafBoxMaxVolume, const bool useVariance) {
this->Clear();
if ((maxElemsPerLeaf == 0) && (leafBoxMaxVolume <= ((ScalarType)0))) {
return (false);
}
const unsigned int size = (unsigned int)std::distance(oBegin, oEnd);
this->pObjects.reserve(size);
for (OBJITERATOR oi=oBegin; oi!=oEnd; ++oi) {
this->pObjects.push_back(objPtr(*oi));
}
this->pRoot = ClassType::BoundObjects(0, this->pObjects.begin(), this->pObjects.end(), size, maxElemsPerLeaf, leafBoxMaxVolume, useVariance, objBox, objBarycenter);
return (this->pRoot != 0);
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
template <class OBJBOXFUNCT, class OBJBARYCENTERFUNCT>
typename AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::NodeType * AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::BoundObjects(NodeType * parent, const ObjPtrVectorIterator & oBegin, const ObjPtrVectorIterator & oEnd, const unsigned int size, const unsigned int maxElemsPerLeaf, const ScalarType & leafBoxMaxVolume, const bool useVariance, OBJBOXFUNCT & getBox, OBJBARYCENTERFUNCT & getBarycenter) {
if (size <= 0) {
return (0);
}
NodeType * pNode = new NodeType(parent);
if (pNode == 0) {
return (0);
}
pNode->children[0] = 0;
pNode->children[1] = 0;
pNode->oBegin = oBegin;
pNode->oEnd = oEnd;
Box3<ScalarType> bbox;
bbox.SetNull();
for (ObjPtrVectorConstIterator oi=pNode->oBegin; oi!=pNode->oEnd; ++oi) {
Box3<ScalarType> tbox;
getBox(*(*oi), tbox);
bbox.Add(tbox);
}
pNode->boxCenter = bbox.Center();
pNode->boxHalfDims = bbox.Dim() / ((ScalarType)2);
const bool bMaxObjectsReached = (((maxElemsPerLeaf > 0) && (size <= maxElemsPerLeaf)) || (size == 1));
const bool bMaxVolumeReached = ((leafBoxMaxVolume > ((ScalarType)0)) && (bbox.Volume() <= leafBoxMaxVolume));
const bool isLeaf = bMaxObjectsReached || bMaxVolumeReached;
if (isLeaf) {
pNode->splitAxis = 0;
return (pNode);
}
CoordType pSplit;
if (useVariance) {
CoordType mean((ScalarType)0, (ScalarType)0, (ScalarType)0);
CoordType variance((ScalarType)0, (ScalarType)0, (ScalarType)0);
for (ObjPtrVectorIterator oi=oBegin; oi!=oEnd; ++oi) {
CoordType bc;
getBarycenter(*(*oi), bc);
mean += bc;
variance[0] += bc[0] * bc[0];
variance[1] += bc[1] * bc[1];
variance[2] += bc[2] * bc[2];
}
variance[0] -= (mean[0] * mean[0]) / ((ScalarType)size);
variance[1] -= (mean[1] * mean[1]) / ((ScalarType)size);
variance[2] -= (mean[2] * mean[2]) / ((ScalarType)size);
pSplit = variance;
}
else {
pSplit = pNode->boxHalfDims;
}
ScalarType maxDim = pSplit[0];
unsigned char splitAxis = 0;
if (maxDim < pSplit[1]) {
maxDim = pSplit[1];
splitAxis = 1;
}
if (maxDim < pSplit[2]) {
maxDim = pSplit[2];
splitAxis = 2;
}
pNode->splitAxis = splitAxis;
ObjPtrVectorIterator median;
const int lSize = ClassType::BalanceMedian(pNode->oBegin, pNode->oEnd, size, splitAxis, getBarycenter, median);
const int rSize = size - lSize;
if (lSize > 0) {
pNode->children[0] = ClassType::BoundObjects(pNode, pNode->oBegin, median, lSize, maxElemsPerLeaf, leafBoxMaxVolume, useVariance, getBox, getBarycenter);
if (pNode->children[0] == 0) {
delete pNode;
return (0);
}
}
if (rSize > 0) {
pNode->children[1] = ClassType::BoundObjects(pNode, median, pNode->oEnd, rSize, maxElemsPerLeaf, leafBoxMaxVolume, useVariance, getBox, getBarycenter);
if (pNode->children[1] == 0) {
delete pNode;
return (0);
}
}
return (pNode);
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
template <class OBJBARYCENTERFUNCT>
int AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::BalanceMedian(const ObjPtrVectorIterator & oBegin, const ObjPtrVectorIterator & oEnd, const int size, const int splitAxis, OBJBARYCENTERFUNCT & getBarycenter, ObjPtrVectorIterator & medianIter) {
const int iMedian = (size + 1) / 2;
ObjPtrVectorIterator l, r, i, j;
ObjPtr iTmp;
ScalarType pos;
ObjPtrVectorIterator median = oBegin + iMedian;
CoordType bc;
l = oBegin;
r = oEnd - 1;
while (l < r) {
getBarycenter(*(*r), bc);
pos = bc[splitAxis];
i = l;
j = r - 1;
while (true) {
getBarycenter(*(*i), bc);
while ((bc[splitAxis] <= pos) && (i < r)) {
i++;
getBarycenter(*(*i), bc);
}
getBarycenter(*(*j), bc);
while ((bc[splitAxis] > pos) && (j > l)) {
j--;
getBarycenter(*(*j), bc);
}
if (i >= j) {
break;
}
iTmp = (*i);
(*i) = (*j);
(*j) = iTmp;
}
iTmp = (*i);
(*i) = (*r);
(*r) = iTmp;
if (i >= (median)) {
r = i - 1;
}
if (i <= (median)) {
l = i + 1;
}
}
medianIter = median;
return (iMedian);
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeNode::AABBBinaryTreeNode(NodeType * pParent) {
this->parent = pParent;
this->children[0] = 0;
this->children[1] = 0;
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeNode::~AABBBinaryTreeNode(void) {
delete this->children[0];
delete this->children[1];
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
void AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeNode::Clear(void) {
delete this->children[0];
this->children[0] = 0;
delete this->children[1];
this->children[1] = 0;
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
bool AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeNode::IsLeaf(void) const {
return ((this->children[0] == 0) && (this->children[1] == 0));
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
unsigned int AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeNode::ObjectsCount(void) const {
return ((unsigned int)(std::distance(this->oBegin, this->oEnd)));
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
unsigned int & AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeNode::Flags(void) {
return (this->sharedData.flags);
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
const unsigned int & AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeNode::Flags(void) const {
return (this->sharedData.flags);
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
int & AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeNode::IntValue(void) {
return (this->sharedData.intValue);
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
const int & AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeNode::IntValue(void) const {
return (this->sharedData.intValue);
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
unsigned int & AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeNode::UIntValue(void) {
return (this->sharedData.uintValue);
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
const unsigned int & AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeNode::UIntValue(void) const {
return (this->sharedData.uintValue);
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
typename AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::ScalarType & AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeNode::ScalarValue(void) {
return (this->sharedData.scalarValue);
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
const typename AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::ScalarType & AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeNode::ScalarValue(void) const {
return (this->sharedData.scalarValue);
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
void * & AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeNode::PtrValue(void) {
return (this->sharedData.ptrValue);
}
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
const void * & AABBBinaryTree<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeNode::PtrValue(void) const {
return (this->sharedData.ptrValue);
}
} // end namespace vcg
#endif // #ifndef __VCGLIB_AABBBINARYTREE_TYPE_H

View File

@ -0,0 +1,148 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
****************************************************************************/
#ifndef __VCGLIB_AABBBINARYTREE_CLOSEST_H
#define __VCGLIB_AABBBINARYTREE_CLOSEST_H
// stl headers
#include <limits>
#include <vector>
// vcg headers
#include <vcg/math/base.h>
#include <vcg/space/index/aabb_binary_tree/utils.h>
namespace vcg {
template <class TREETYPE>
class AABBBinaryTreeClosest {
public:
typedef AABBBinaryTreeClosest<TREETYPE> ClassType;
typedef TREETYPE TreeType;
typedef typename TreeType::ScalarType ScalarType;
typedef typename TreeType::CoordType CoordType;
typedef typename TreeType::NodeType NodeType;
typedef typename TreeType::ObjPtr ObjPtr;
template <class OBJPOINTDISTANCEFUNCT>
static inline ObjPtr Closest(TreeType & tree, OBJPOINTDISTANCEFUNCT & getPointDistance, const CoordType & p, const ScalarType & maxDist, ScalarType & minDist, CoordType & q) {
typedef OBJPOINTDISTANCEFUNCT ObjPointDistanceFunct;
typedef std::vector<NodeType *> NodePtrVector;
typedef typename NodePtrVector::const_iterator NodePtrVector_ci;
NodeType * pRoot = tree.pRoot;
if (pRoot == 0) {
return (0);
}
NodePtrVector clist1;
NodePtrVector clist2;
NodePtrVector leaves;
NodePtrVector * candidates = &clist1;
NodePtrVector * newCandidates = &clist2;
clist1.reserve(tree.pObjects.size());
clist2.reserve(tree.pObjects.size());
leaves.reserve(tree.pObjects.size());
clist1.resize(0);
clist2.resize(0);
leaves.resize(0);
ScalarType minMaxDist = maxDist * maxDist;
candidates->push_back(pRoot);
while (!candidates->empty()) {
newCandidates->resize(0);
for (NodePtrVector_ci bv=candidates->begin(); bv!=candidates->end(); ++bv) {
const CoordType dc = Abs(p - (*bv)->boxCenter);
const ScalarType maxDist = (dc + (*bv)->boxHalfDims).SquaredNorm();
(*bv)->ScalarValue() = LowClampToZero(dc - (*bv)->boxHalfDims).SquaredNorm();
if (maxDist < minMaxDist) {
minMaxDist = maxDist;
}
}
for (NodePtrVector_ci ci=candidates->begin(); ci!=candidates->end(); ++ci) {
if ((*ci)->ScalarValue() < minMaxDist) {
if ((*ci)->IsLeaf()) {
leaves.push_back(*ci);
}
else {
if ((*ci)->children[0] != 0) {
newCandidates->push_back((*ci)->children[0]);
}
if ((*ci)->children[1] != 0) {
newCandidates->push_back((*ci)->children[1]);
}
}
}
}
NodePtrVector * cSwap = candidates;
candidates = newCandidates;
newCandidates = cSwap;
}
clist1.clear();
clist2.clear();
ObjPtr closestObject = 0;
CoordType closestPoint;
ScalarType closestDist = math::Sqrt(minMaxDist) + std::numeric_limits<ScalarType>::epsilon();
ScalarType closestDistSq = closestDist * closestDist;
for (NodePtrVector_ci ci=leaves.begin(); ci!=leaves.end(); ++ci) {
if ((*ci)->ScalarValue() < closestDistSq) {
for (typename TreeType::ObjPtrVectorConstIterator si=(*ci)->oBegin; si!=(*ci)->oEnd; ++si) {
if (getPointDistance(*(*si), p, closestDist, closestPoint)) {
closestDistSq = closestDist * closestDist;
closestObject = (*si);
}
}
}
}
leaves.clear();
q = closestPoint;
minDist = closestDist;
return (closestObject);
}
};
} // end namespace vcg
#endif // #ifndef __VCGLIB_AABBBINARYTREE_CLOSEST_H

View File

@ -0,0 +1,102 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
****************************************************************************/
#ifndef __VCGLIB_FACEFUNCTORS
#define __VCGLIB_FACEFUNCTORS
// vcg headers
#include <vcg/space/point3.h>
#include <vcg/space/box3.h>
#include <vcg/space/line3.h>
#include <vcg/space/intersection3.h>
#include <vcg/simplex/face/distance.h>
namespace vcg {
class FaceBarycenterFunctor {
public:
template <class FACETYPE, class COORDTYPE>
inline void operator () (const FACETYPE & f, COORDTYPE & b) {
b = COORDTYPE::Construct(f.Barycenter());
}
};
class FaceBoxFunctor {
public:
template <class FACETYPE, class BOXTYPE>
inline void operator () (const FACETYPE & f, BOXTYPE & b) {
b.Set(Point3<BOXTYPE::ScalarType>::Construct(f.P(0)));
b.Add(Point3<BOXTYPE::ScalarType>::Construct(f.P(1)));
b.Add(Point3<BOXTYPE::ScalarType>::Construct(f.P(2)));
}
};
class FacePointDistanceFunctor {
public:
template <class FACETYPE, class COORDTYPE>
inline bool operator () (const FACETYPE & f, const COORDTYPE & p, typename COORDTYPE::ScalarType & minDist, COORDTYPE & q) {
const Point3<typename FACETYPE::ScalarType> fp = Point3<typename FACETYPE::ScalarType>::Construct(p);
Point3<typename FACETYPE::ScalarType> fq;
typename FACETYPE::ScalarType md = (typename FACETYPE::ScalarType)(minDist);
const bool ret = face::PointDistance(f, fp, md, fq);
minDist = (typename COORDTYPE::ScalarType)(md);
q = COORDTYPE::Construct(fq);
return (ret);
}
};
template <bool BACKFACETEST = true>
class FaceRayIntersectFunctor {
public:
template <class FACETYPE, class COORDTYPE>
inline bool operator () (const FACETYPE & f, const COORDTYPE & rayOrigin, const COORDTYPE & rayDirection, typename COORDTYPE::ScalarType & t, COORDTYPE & q) {
typedef typename COORDTYPE::ScalarType ScalarType;
Line3<ScalarType, false> ln(rayOrigin, rayDirection);
ScalarType a;
ScalarType b;
bool bret = Intersection(ln, f.P(0), f.P(1), f.P(2), a, b, t);
if (BACKFACETEST) {
if (!bret) {
bret = Intersection(ln, f.P(0), f.P(2), f.P(1), a, b, t);
}
}
if (bret) {
q = rayOrigin + rayDirection * t;
return (true);
}
return (false);
}
};
} // end namespace vcg
#endif // #ifndef __VCGLIB_FACEFUNCTORS

View File

@ -0,0 +1,200 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
****************************************************************************/
#ifndef __VCGLIB_AABBBINARYTREE_FRUSTUMCULL_H
#define __VCGLIB_AABBBINARYTREE_FRUSTUMCULL_H
// vcg headers
#include <vcg/space/point3.h>
#include <vcg/space/plane3.h>
/***************************************************************************************/
namespace vcg {
template <class TREETYPE>
class AABBBinaryTreeFrustumCull {
public:
typedef AABBBinaryTreeFrustumCull<TREETYPE> ClassType;
typedef TREETYPE TreeType;
typedef typename TreeType::ScalarType ScalarType;
typedef typename TreeType::CoordType CoordType;
typedef typename TreeType::NodeType NodeType;
typedef typename TreeType::ObjPtr ObjPtr;
protected:
class VFrustumPlane {
public:
CoordType normal;
ScalarType offset;
unsigned int pVertexIndex[3];
};
class VFrustum {
public:
VFrustumPlane planes[6];
};
public:
enum {
FC_FIRST_PLANE_BIT = 0,
FC_PARTIALLY_VISIBLE_BIT = (1 << (FC_FIRST_PLANE_BIT + 3)),
FC_FULLY_VISIBLE_BIT = (1 << (FC_FIRST_PLANE_BIT + 4))
};
static inline bool IsPartiallyVisible(const NodeType * node) {
return ((node->Flags() & FC_PARTIALLY_VISIBLE_BIT) != 0);
}
static inline bool IsFullyVisible(const NodeType * node) {
return ((node->Flags() & FC_FULLY_VISIBLE_BIT) != 0);
}
static inline bool IsVisible(const NodeType * node) {
return ((node->Flags() & (FC_PARTIALLY_VISIBLE_BIT | FC_FULLY_VISIBLE_BIT)) != 0);
}
static inline void Initialize(TreeType & tree) {
NodeType * pRoot = tree.pRoot;
if (pRoot == 0) {
return;
}
ClassType::InitializeNodeFlagsRec(pRoot);
}
static inline void FrustumCull(TreeType & tree, const Plane3<ScalarType> frustumPlanes[6], const unsigned int minNodeObjectsCount) {
NodeType * pRoot = tree.pRoot;
if (pRoot == 0) {
return;
}
VFrustum frustum;
for (int i=0; i<6; ++i) {
frustum.planes[i].normal = frustumPlanes[i].Direction();
frustum.planes[i].offset = frustumPlanes[i].Offset();
frustum.planes[i].pVertexIndex[0] = (frustum.planes[i].normal[0] >= ((ScalarType)0)) ? (1) : (0);
frustum.planes[i].pVertexIndex[1] = (frustum.planes[i].normal[1] >= ((ScalarType)0)) ? (1) : (0);
frustum.planes[i].pVertexIndex[2] = (frustum.planes[i].normal[2] >= ((ScalarType)0)) ? (1) : (0);
}
const unsigned char inMask = 0x3F;
ClassType::NodeVsFrustum(pRoot, frustum, inMask, minNodeObjectsCount);
}
protected:
static inline void InitializeNodeFlagsRec(NodeType * node) {
node->Flags() &= ~(0x1F);
if (node->children[0] == 0) {
ClassType::InitializeNodeFlagsRec(node->children[0]);
}
if (node->children[1] == 0) {
ClassType::InitializeNodeFlagsRec(node->children[1]);
}
}
static inline void NodeVsFrustum(NodeType * node, const VFrustum & f, unsigned char inMask, unsigned int minNodeObjectsCount) {
const CoordType bminmax[2] = {
node->boxCenter - node->boxHalfDims,
node->boxCenter + node->boxHalfDims,
};
const unsigned int firstFail = (unsigned int)((node->Flags() >> FC_FIRST_PLANE_BIT) & 0x7);
const VFrustumPlane * fp = f.planes + firstFail;
unsigned char k = 1 << firstFail;
unsigned char newMask = 0x0;
bool fullInside = true;
node->Flags() &= ~(FC_PARTIALLY_VISIBLE_BIT | FC_FULLY_VISIBLE_BIT);
if ((k & inMask) != 0) {
if (
((fp->normal[0] * bminmax[fp->pVertexIndex[0]][0]) +
(fp->normal[1] * bminmax[fp->pVertexIndex[1]][1]) +
(fp->normal[2] * bminmax[fp->pVertexIndex[2]][2]) +
(fp->offset)) < ((ScalarType)0)
) {
return;
}
if (
((fp->normal[0] * bminmax[1 - fp->pVertexIndex[0]][0]) +
(fp->normal[1] * bminmax[1 - fp->pVertexIndex[1]][1]) +
(fp->normal[2] * bminmax[1 - fp->pVertexIndex[2]][2]) +
(fp->offset)) < ((ScalarType)0)
) {
newMask |= k;
fullInside = false;
}
}
k = 1;
for (unsigned int i=0; k<=inMask; ++i, k<<=1) {
if ((i != firstFail) && ((k & inMask) != 0)) {
fp = f.planes + i;
if (
((fp->normal[0] * bminmax[fp->pVertexIndex[0]][0]) +
(fp->normal[1] * bminmax[fp->pVertexIndex[1]][1]) +
(fp->normal[2] * bminmax[fp->pVertexIndex[2]][2]) +
(fp->offset)) < ((ScalarType)0)
) {
node->Flags() = (node->Flags() & ((~0x0) & (0x7 << ClassType::FC_FIRST_PLANE_BIT))) | (i << ClassType::FC_FIRST_PLANE_BIT);
return;
}
if (
((fp->normal[0] * bminmax[1 - fp->pVertexIndex[0]][0]) +
(fp->normal[1] * bminmax[1 - fp->pVertexIndex[1]][1]) +
(fp->normal[2] * bminmax[1 - fp->pVertexIndex[2]][2]) +
(fp->offset)) < ((ScalarType)0)
) {
newMask |= k;
fullInside = false;
}
}
}
if (fullInside || (node->ObjectsCount() <= minNodeObjectsCount)) {
node->Flags() |= FC_FULLY_VISIBLE_BIT;
return;
}
node->Flags() |= FC_PARTIALLY_VISIBLE_BIT;
if (node->children[0] != 0) {
ClassType::NodeVsFrustum(node->children[0], f, newMask, minNodeObjectsCount);
}
if (node->children[1] != 0) {
ClassType::NodeVsFrustum(node->children[1], f, newMask, minNodeObjectsCount);
}
}
};
} // end namespace vcg
#endif // #ifndef __VCGLIB_AABBBINARYTREE_FRUSTUMCULL_H

View File

@ -0,0 +1,155 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
****************************************************************************/
#ifndef __VCGLIB_AABBBINARYTREE_KCLOSEST_H
#define __VCGLIB_AABBBINARYTREE_KCLOSEST_H
// stl headers
#include <queue>
#include <deque>
// vcg headers
#include <vcg/space/index/aabb_binary_tree/utils.h>
namespace vcg {
template <class TREETYPE>
class AABBBinaryTreeKClosest {
public:
typedef AABBBinaryTreeKClosest<TREETYPE> ClassType;
typedef TREETYPE TreeType;
typedef typename TreeType::ScalarType ScalarType;
typedef typename TreeType::CoordType CoordType;
typedef typename TreeType::NodeType NodeType;
typedef typename TreeType::ObjPtr ObjPtr;
protected:
class ClosestObjType {
public:
ObjPtr pObj;
ScalarType minDist;
CoordType closestPt;
};
class CompareClosest {
public:
bool operator () (const ClosestObjType & a, const ClosestObjType & b) {
return (a.minDist < b.minDist);
}
};
typedef std::priority_queue<ClosestObjType, std::deque<ClosestObjType>, CompareClosest> PQueueType;
public:
template <class OBJPOINTDISTANCEFUNCT, class OBJPTRCONTAINERTYPE, class DISTCONTAINERTYPE, class POINTCONTAINERTYPE>
static inline unsigned int KClosest(TreeType & tree, OBJPOINTDISTANCEFUNCT & getPointDistance, const unsigned int k, const CoordType & p, const ScalarType & maxDist, OBJPTRCONTAINERTYPE & objects, DISTCONTAINERTYPE & distances, POINTCONTAINERTYPE & points) {
typedef std::vector<NodeType *> NodePtrVector;
typedef typename NodePtrVector::const_iterator NodePtrVector_ci;
if (k == 0) {
return (0);
}
NodeType * pRoot = tree.pRoot;
if (pRoot == 0) {
return (0);
}
PQueueType pq;
ScalarType mindmax = maxDist;
ClassType::DepthFirstCollect(pRoot, getPointDistance, k, p, mindmax, pq);
const unsigned int sz = (unsigned int)(pq.size());
while (!pq.empty()) {
ClosestObjType cobj = pq.top();
pq.pop();
objects.push_back(cobj.pObj);
distances.push_back(cobj.minDist);
points.push_back(cobj.closestPt);
}
return (sz);
}
protected:
template <class OBJPOINTDISTANCEFUNCT>
static void DepthFirstCollect(NodeType * node, OBJPOINTDISTANCEFUNCT & getPointDistance, const unsigned int k, const CoordType & p, ScalarType & mindmax, PQueueType & pq) {
const CoordType dc = Abs(p - node->boxCenter);
if (pq.size() >= k) {
const ScalarType dmin = LowClampToZero(dc - node->boxHalfDims).SquaredNorm();
if (dmin >= mindmax) {
return;
}
}
if (node->IsLeaf()) {
bool someInserted = true;
for (typename TreeType::ObjPtrVectorConstIterator si=node->oBegin; si!=node->oEnd; ++si) {
ScalarType minDst = (pq.size() >= k) ? (pq.top().minDist) : (mindmax);
ClosestObjType cobj;
if (getPointDistance(*(*si), p, minDst, cobj.closestPt)) {
someInserted = true;
cobj.pObj = (*si);
cobj.minDist = minDst;
if (pq.size() >= k) {
pq.pop();
}
pq.push(cobj);
}
}
if (someInserted) {
if (pq.size() >= k) {
const ScalarType dmax = pq.top().minDist;
const ScalarType sqdmax = dmax * dmax;
if (sqdmax < mindmax) {
mindmax = sqdmax;
}
}
}
}
else {
if (node->children[0] != 0) {
ClassType::DepthFirstCollect(node->children[0], getPointDistance, k, p, mindmax, pq);
}
if (node->children[1] != 0) {
ClassType::DepthFirstCollect(node->children[1], getPointDistance, k, p, mindmax, pq);
}
}
}
};
} // end namespace vcg
#endif // #ifndef __VCGLIB_AABBBINARYTREE_KCLOSEST_H

View File

@ -0,0 +1,168 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
****************************************************************************/
#ifndef __VCGLIB_AABBBINARYTREE_RAY_H
#define __VCGLIB_AABBBINARYTREE_RAY_H
// stl headers
#include <limits>
/***************************************************************************************/
namespace vcg {
template <class TREETYPE>
class AABBBinaryTreeRay {
public:
typedef AABBBinaryTreeRay<TREETYPE> ClassType;
typedef TREETYPE TreeType;
typedef typename TreeType::ScalarType ScalarType;
typedef typename TreeType::CoordType CoordType;
typedef typename TreeType::NodeType NodeType;
typedef typename TreeType::ObjPtr ObjPtr;
template <class OBJRAYISECTFUNCT>
static inline ObjPtr Ray(TreeType & tree, OBJRAYISECTFUNCT & rayIntersection, const CoordType & rayOrigin, const CoordType & rayDirection, ScalarType & t, CoordType & q) {
typedef std::vector<NodeType *> NodePtrVector;
typedef typename NodePtrVector::const_iterator NodePtrVector_ci;
NodeType * pRoot = tree.pRoot;
if (pRoot == 0) {
return (0);
}
ScalarType rayT = std::numeric_limits<ScalarType>::max();
CoordType pRes;
Ray3Ex rayex;
rayex.origin = rayOrigin;
rayex.direction = rayDirection;
rayex.invDirection[0] = ((ScalarType)1) / rayDirection[0];
rayex.invDirection[1] = ((ScalarType)1) / rayDirection[1];
rayex.invDirection[2] = ((ScalarType)1) / rayDirection[2];
rayex.sign[0] = (rayex.invDirection[0] < ((ScalarType)0)) ? (1) : (0);
rayex.sign[1] = (rayex.invDirection[1] < ((ScalarType)0)) ? (1) : (0);
rayex.sign[2] = (rayex.invDirection[2] < ((ScalarType)0)) ? (1) : (0);
ObjPtr closestObj = 0;
ClassType::DepthFirstRayIsect(pRoot, rayIntersection, rayex, rayT, pRes, closestObj);
if (closestObj == 0) {
return (0);
}
t = rayT;
q = pRes;
return (closestObj);
}
protected:
class Ray3Ex {
public:
CoordType origin;
CoordType direction;
CoordType invDirection;
unsigned char sign[3];
};
static inline bool IntersectionBoxRay(const CoordType & boxCenter, const CoordType & boxHalfDims, const Ray3Ex & ray, ScalarType & t0) {
const CoordType bounds[2] = {
boxCenter - boxHalfDims,
boxCenter + boxHalfDims
};
ScalarType tmin, tmax;
ScalarType tcmin, tcmax;
tmin = (bounds[ray.sign[0]][0] - ray.origin[0]) * ray.invDirection[0];
tmax = (bounds[1 - ray.sign[0]][0] - ray.origin[0]) * ray.invDirection[0];
tcmin = (bounds[ray.sign[1]][1] - ray.origin[1]) * ray.invDirection[1];
tcmax = (bounds[1 - ray.sign[1]][1] - ray.origin[1]) * ray.invDirection[1];
if ((tmin > tcmax) || (tcmin > tmax)) { return (false); }
if (tcmin > tmin) { tmin = tcmin; }
if (tcmax < tmax) { tmax = tcmax; }
tcmin = (bounds[ray.sign[2]][2] - ray.origin[2]) * ray.invDirection[2];
tcmax = (bounds[1-ray.sign[2]][2] - ray.origin[2]) * ray.invDirection[2];
if ((tmin > tcmax) || (tcmin > tmax)) { return (false); }
if (tcmin > tmin) { tmin = tcmin; }
//if (tcmax < tmax) { tmax = tcmax; }
t0 = (tmin >= ((ScalarType)0)) ? (tmin) :((ScalarType)0);
return (true);
}
template <class OBJRAYISECTFUNCT>
static inline void DepthFirstRayIsect(const NodeType * node, OBJRAYISECTFUNCT & rayIntersection, const Ray3Ex & ray, ScalarType & rayT, CoordType & res, ObjPtr & closestObj) {
ScalarType rt;
CoordType pt;
if (!ClassType::IntersectionBoxRay(node->boxCenter, node->boxHalfDims, ray, rt)) {
return;
}
if (rt >= rayT) {
return;
}
if (node->IsLeaf()) {
ObjPtr cObj = 0;
ScalarType ar;
CoordType ap;
rt = std::numeric_limits<ScalarType>::max();
for (typename TreeType::ObjPtrVectorConstIterator si=node->oBegin; si!=node->oEnd; ++si) {
if (rayIntersection(*(*si), ray.origin, ray.direction, ar, ap)) {
if (ar < rt) {
rt = ar;
pt = ap;
cObj = (*si);
}
}
}
if (rt < rayT) {
rayT = rt;
res = pt;
closestObj = cObj;
}
}
else {
if (node->children[0] != 0) {
ClassType::DepthFirstRayIsect(node->children[0], rayIntersection, ray, rayT, res, closestObj);
}
if (node->children[1] != 0) {
ClassType::DepthFirstRayIsect(node->children[1], rayIntersection, ray, rayT, res, closestObj);
}
}
}
};
} // end namespace vcg
#endif // #ifndef __VCGLIB_AABBBINARYTREE_RAY_H

View File

@ -0,0 +1,74 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
****************************************************************************/
#ifndef __VCGLIB_AABBBINARYTREE_UTILS_H
#define __VCGLIB_AABBBINARYTREE_UTILS_H
// vcg headers
#include <vcg/math/base.h>
#include <vcg/space/point3.h>
/***************************************************************************************/
namespace vcg {
class EmptyClass {
public:
typedef EmptyClass ClassType;
};
class ObjPtrIteratorFunctor {
public:
typedef ObjPtrIteratorFunctor ClassType;
template <class T>
inline T * operator () (T & obj) {
return (&obj);
}
template <class T>
inline T * operator () (T * & obj) {
return (obj);
}
};
template <class SCALARTYPE>
inline Point3<SCALARTYPE> Abs(const Point3<SCALARTYPE> & p) {
return (Point3<SCALARTYPE>(math::Abs(p[0]), math::Abs(p[1]), math::Abs(p[2])));
}
template <class SCALARTYPE>
inline Point3<SCALARTYPE> LowClampToZero(const Point3<SCALARTYPE> & p) {
return (Point3<SCALARTYPE>(math::Max(p[0], (SCALARTYPE)0), math::Max(p[1], (SCALARTYPE)0), math::Max(p[2], (SCALARTYPE)0)));
}
} // end namespace vcg
#endif // #ifndef __VCGLIB_AABBBINARYTREE_UTILS_H