Old versions removed. Now AABBBinaryTree has its own folder.
This commit is contained in:
parent
82c6f3e0b8
commit
bcd64129e2
|
@ -1,335 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
* VCGLib o o *
|
|
||||||
* Visual and Computer Graphics Library o o *
|
|
||||||
* _ O _ *
|
|
||||||
* Copyright(C) 2005 \/)\/ *
|
|
||||||
* 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 $
|
|
||||||
Revision 1.2 2005/09/11 11:45:53 m_di_benedetto
|
|
||||||
First Commit
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __VCGLIB_AABBBINARYTREE
|
|
||||||
#define __VCGLIB_AABBBINARYTREE
|
|
||||||
|
|
||||||
// stl headers
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// vcg headers
|
|
||||||
#include <vcg/space/point3.h>
|
|
||||||
#include <vcg/space/box3.h>
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************************/
|
|
||||||
|
|
||||||
namespace vcg {
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
Class AABBBinaryTree
|
|
||||||
|
|
||||||
SAMPLE USAGE:
|
|
||||||
|
|
||||||
NOTES:
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
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 int numObjects;
|
|
||||||
NodeAuxDataType auxData;
|
|
||||||
|
|
||||||
inline AABBBinaryTreeNode(AABBBinaryTreeNode * pParent = 0);
|
|
||||||
inline ~AABBBinaryTreeNode(void);
|
|
||||||
|
|
||||||
inline void Clear(void);
|
|
||||||
|
|
||||||
inline bool IsLeaf(void) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
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) {
|
|
||||||
const Box3<ScalarType> tbox = getBox(*(*oi));
|
|
||||||
bbox.Add(tbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
pNode->boxCenter = bbox.Center();
|
|
||||||
pNode->boxHalfDims = bbox.Dim() / ((ScalarType)2);
|
|
||||||
|
|
||||||
pNode->numObjects = size;
|
|
||||||
|
|
||||||
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) {
|
|
||||||
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) {
|
|
||||||
const CoordType bc = getBarycenter(*(*oi));
|
|
||||||
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];
|
|
||||||
int splitAxis = 0;
|
|
||||||
if (maxDim < pSplit[1]) {
|
|
||||||
maxDim = pSplit[1];
|
|
||||||
splitAxis = 1;
|
|
||||||
}
|
|
||||||
if (maxDim < pSplit[2]) {
|
|
||||||
maxDim = pSplit[2];
|
|
||||||
splitAxis = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
l = oBegin;
|
|
||||||
r = oEnd - 1;
|
|
||||||
|
|
||||||
while (l < r) {
|
|
||||||
pos = getBarycenter(*(*r))[splitAxis];
|
|
||||||
|
|
||||||
i = l;
|
|
||||||
j = r - 1;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
while ((getBarycenter(*(*i))[splitAxis] <= pos) && (i < r)) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
while ((getBarycenter(*(*j))[splitAxis] > pos) && (j > l)) {
|
|
||||||
j--;
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
this->numObjects = 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;
|
|
||||||
|
|
||||||
this->numObjects = 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace vcg
|
|
||||||
|
|
||||||
#endif // #ifndef __VCGLIB_AABBBINARYTREE
|
|
|
@ -1,364 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
* VCGLib o o *
|
|
||||||
* Visual and Computer Graphics Library o o *
|
|
||||||
* _ O _ *
|
|
||||||
* Copyright(C) 2005 \/)\/ *
|
|
||||||
* 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 $
|
|
||||||
Revision 1.3 2005/09/16 10:04:15 m_di_benedetto
|
|
||||||
Modified interface, added GetKClosest().
|
|
||||||
|
|
||||||
Revision 1.2 2005/09/11 11:46:21 m_di_benedetto
|
|
||||||
First Commit
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __VCGLIB_AABBBINARYTREESEARCH
|
|
||||||
#define __VCGLIB_AABBBINARYTREESEARCH
|
|
||||||
|
|
||||||
// stl headers
|
|
||||||
#include <limits>
|
|
||||||
#include <vector>
|
|
||||||
#include <queue>
|
|
||||||
#include <deque>
|
|
||||||
|
|
||||||
// vcg headers
|
|
||||||
#include <vcg/space/index/aabb_binary_tree.h>
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************************/
|
|
||||||
|
|
||||||
namespace vcg {
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
Class AABBBinaryTreeSearch
|
|
||||||
|
|
||||||
SAMPLE USAGE:
|
|
||||||
|
|
||||||
NOTES:
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
template <class OBJTYPE, class SCALARTYPE, class NODEUSERATATYPE>
|
|
||||||
class AABBBinaryTreeSearch {
|
|
||||||
public:
|
|
||||||
struct NodeSearchDataType {
|
|
||||||
SCALARTYPE minDist;
|
|
||||||
};
|
|
||||||
struct NodeAuxDataType {
|
|
||||||
NodeSearchDataType searchData;
|
|
||||||
NODEUSERATATYPE userData;
|
|
||||||
};
|
|
||||||
typedef AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEUSERATATYPE> ClassType;
|
|
||||||
typedef OBJTYPE ObjType;
|
|
||||||
typedef SCALARTYPE ScalarType;
|
|
||||||
typedef NODEUSERATATYPE NodeUserDataType;
|
|
||||||
typedef AABBBinaryTree<ObjType, ScalarType, NodeAuxDataType> TreeType;
|
|
||||||
typedef typename TreeType::ObjPtr ObjPtr;
|
|
||||||
typedef typename TreeType::CoordType CoordType;
|
|
||||||
|
|
||||||
inline AABBBinaryTreeSearch(void);
|
|
||||||
inline ~AABBBinaryTreeSearch(void);
|
|
||||||
|
|
||||||
inline TreeType & Tree(void);
|
|
||||||
inline const TreeType & Tree(void) const;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
inline void Clear(void);
|
|
||||||
|
|
||||||
template <class OBJPOINTDISTANCEFUNCT>
|
|
||||||
ObjPtr GetClosest(OBJPOINTDISTANCEFUNCT & getPointDistance, const CoordType & p, ScalarType & minDist, CoordType & res) const;
|
|
||||||
|
|
||||||
template <class OBJPOINTDISTANCEFUNCT, class OBJPTRCONTAINER, class DISTCONTAINER, class POINTCONTAINER>
|
|
||||||
unsigned int GetKClosests(OBJPOINTDISTANCEFUNCT & getPointDistance, const unsigned int k, const CoordType & p, OBJPTRCONTAINER & closestObjs, DISTCONTAINER & distances, POINTCONTAINER & closestPts) const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
struct ClosestObjType {
|
|
||||||
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<typename ClassType::ClosestObjType, std::deque<typename ClassType::ClosestObjType>, typename ClassType::CompareClosest> PQueueType;
|
|
||||||
|
|
||||||
TreeType tree;
|
|
||||||
|
|
||||||
static inline CoordType Abs(const CoordType & p);
|
|
||||||
static inline CoordType LowerClamp(const CoordType & p, const ScalarType & r);
|
|
||||||
static inline ScalarType MinimumMaxSquareDistance(const ScalarType & currMinMaxDist, const std::vector<typename TreeType::NodeType *> & n, const CoordType & p);
|
|
||||||
static inline void MinMaxSquareDistance(const typename TreeType::NodeType * n, const CoordType & p, ScalarType & dmin, ScalarType & dmax);
|
|
||||||
|
|
||||||
template <class OBJPOINTDISTANCEFUNCT>
|
|
||||||
static inline void DepthFirstCollect(const CoordType & p, typename TreeType::NodeType * node, ScalarType & mindmax, const unsigned int k, PQueueType & pq, OBJPOINTDISTANCEFUNCT & getPointDistance);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
|
|
||||||
AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::AABBBinaryTreeSearch(void) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
|
|
||||||
AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::~AABBBinaryTreeSearch(void) {
|
|
||||||
this->Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
|
|
||||||
typename AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::TreeType & AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::Tree(void) {
|
|
||||||
return (this->tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
|
|
||||||
const typename AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::TreeType & AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::Tree(void) const {
|
|
||||||
return (this->tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
|
|
||||||
template <class OBJITERATOR, class OBJITERATORPTRFUNCT, class OBJBOXFUNCT, class OBJBARYCENTERFUNCT>
|
|
||||||
bool AABBBinaryTreeSearch<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) {
|
|
||||||
return (this->tree.Set(oBegin, oEnd, objPtr, objBox, objBarycenter, maxElemsPerLeaf, leafBoxMaxVolume, useVariance));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
|
|
||||||
void AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::Clear(void) {
|
|
||||||
this->tree.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
|
|
||||||
template <class OBJPOINTDISTANCEFUNCT>
|
|
||||||
typename AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::ObjPtr AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::GetClosest(OBJPOINTDISTANCEFUNCT & getPointDistance, const CoordType & p, ScalarType & minDist, CoordType & res) const {
|
|
||||||
typedef std::vector<typename TreeType::NodeType *> NodePtrVector;
|
|
||||||
typedef typename NodePtrVector::const_iterator NodePtrVector_ci;
|
|
||||||
|
|
||||||
const TreeType & t = this->tree;
|
|
||||||
TreeType::NodeType * pRoot = t.pRoot;
|
|
||||||
|
|
||||||
if (pRoot == 0) {
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
NodePtrVector clist1;
|
|
||||||
NodePtrVector clist2;
|
|
||||||
NodePtrVector leaves;
|
|
||||||
|
|
||||||
NodePtrVector * candidates = &clist1;
|
|
||||||
NodePtrVector * newCandidates = &clist2;
|
|
||||||
|
|
||||||
clist1.reserve(t.pObjects.size());
|
|
||||||
clist2.reserve(t.pObjects.size());
|
|
||||||
leaves.reserve(t.pObjects.size());
|
|
||||||
|
|
||||||
clist1.resize(0);
|
|
||||||
clist2.resize(0);
|
|
||||||
leaves.resize(0);
|
|
||||||
|
|
||||||
#ifdef max
|
|
||||||
#undef max
|
|
||||||
#endif
|
|
||||||
ScalarType minMaxDist = std::numeric_limits<ScalarType>::max();
|
|
||||||
|
|
||||||
candidates->push_back(t.pRoot);
|
|
||||||
|
|
||||||
while (!candidates->empty()) {
|
|
||||||
newCandidates->resize(0);
|
|
||||||
minMaxDist = ClassType::MinimumMaxSquareDistance(minMaxDist, *candidates, p);
|
|
||||||
for (NodePtrVector_ci ci=candidates->begin(); ci!=candidates->end(); ++ci) {
|
|
||||||
if ((*ci)->auxData.searchData.minDist < 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 = minMaxDist + std::numeric_limits<ScalarType>::epsilon();
|
|
||||||
|
|
||||||
for (NodePtrVector_ci ci=leaves.begin(); ci!=leaves.end(); ++ci) {
|
|
||||||
if ((*ci)->auxData.searchData.minDist < 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();
|
|
||||||
|
|
||||||
res = closestPoint;
|
|
||||||
minDist = closestDist;
|
|
||||||
|
|
||||||
return (closestObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
|
|
||||||
template <class OBJPOINTDISTANCEFUNCT>
|
|
||||||
void AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::DepthFirstCollect(const CoordType & p, typename TreeType::NodeType * node, ScalarType & mindmax, const unsigned int k, PQueueType & pq, OBJPOINTDISTANCEFUNCT & getPointDistance) {
|
|
||||||
const CoordType dc = ClassType::Abs(p - node->boxCenter);
|
|
||||||
|
|
||||||
if (pq.size() >= k) {
|
|
||||||
const ScalarType dmin = ClassType::LowerClamp(dc - node->boxHalfDims, (ScalarType)0).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) : (std::numeric_limits<ScalarType>::max());
|
|
||||||
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) {
|
|
||||||
DepthFirstCollect(p, node->children[0], mindmax, k, pq, getPointDistance);
|
|
||||||
}
|
|
||||||
if (node->children[1] != 0) {
|
|
||||||
DepthFirstCollect(p, node->children[1], mindmax, k, pq, getPointDistance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
|
|
||||||
template <class OBJPOINTDISTANCEFUNCT, class OBJPTRCONTAINER, class DISTCONTAINER, class POINTCONTAINER>
|
|
||||||
unsigned int AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::GetKClosests(OBJPOINTDISTANCEFUNCT & getPointDistance, const unsigned int k, const CoordType & p, OBJPTRCONTAINER & closestObjs, DISTCONTAINER & distances, POINTCONTAINER & closestPts) const {
|
|
||||||
typedef std::vector<typename TreeType::NodeType *> NodePtrVector;
|
|
||||||
typedef typename NodePtrVector::const_iterator NodePtrVector_ci;
|
|
||||||
|
|
||||||
const TreeType & t = this->tree;
|
|
||||||
TreeType::NodeType * pRoot = t.pRoot;
|
|
||||||
|
|
||||||
if (pRoot == 0) {
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
PQueueType pq;
|
|
||||||
ScalarType mindmax = std::numeric_limits<ScalarType>::max();
|
|
||||||
|
|
||||||
ClassType::DepthFirstCollect(p, pRoot, mindmax, k, pq, getPointDistance);
|
|
||||||
|
|
||||||
const unsigned int sz = pq.size();
|
|
||||||
|
|
||||||
while (!pq.empty()) {
|
|
||||||
ClosestObjType cobj = pq.top();
|
|
||||||
pq.pop();
|
|
||||||
closestObjs.push_back(cobj.pObj);
|
|
||||||
distances.push_back(cobj.minDist);
|
|
||||||
closestPts.push_back(cobj.closestPt);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
|
|
||||||
typename AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::CoordType AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::Abs(const CoordType & p) {
|
|
||||||
return (CoordType(math::Abs(p[0]), math::Abs(p[1]), math::Abs(p[2])));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
|
|
||||||
typename AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::CoordType AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::LowerClamp(const CoordType & p, const ScalarType & r) {
|
|
||||||
return (CoordType(math::Max<ScalarType>(p[0], r), math::Max<ScalarType>(p[1], r), math::Max<ScalarType>(p[2], r)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
|
|
||||||
typename AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::ScalarType AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::MinimumMaxSquareDistance(const ScalarType & currMinMaxDist, const std::vector<typename TreeType::NodeType *> & n, const CoordType & p) {
|
|
||||||
typedef std::vector<typename TreeType::NodeType *> NodePtrVector;
|
|
||||||
typedef typename NodePtrVector::const_iterator NodePtrVector_ci;
|
|
||||||
|
|
||||||
ScalarType minMaxDist = currMinMaxDist;
|
|
||||||
|
|
||||||
for (NodePtrVector_ci bv=n.begin(); bv!=n.end(); ++bv) {
|
|
||||||
const CoordType dc = ClassType::Abs(p - (*bv)->boxCenter);
|
|
||||||
const ScalarType maxDist = (dc + (*bv)->boxHalfDims).SquaredNorm();
|
|
||||||
(*bv)->auxData.searchData.minDist = ClassType::LowerClamp(dc - (*bv)->boxHalfDims, (ScalarType)0).SquaredNorm();
|
|
||||||
if (maxDist < minMaxDist) {
|
|
||||||
minMaxDist = maxDist;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (minMaxDist);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OBJTYPE, class SCALARTYPE, class NODEAUXDATATYPE>
|
|
||||||
void AABBBinaryTreeSearch<OBJTYPE, SCALARTYPE, NODEAUXDATATYPE>::MinMaxSquareDistance(const typename TreeType::NodeType * n, const CoordType & p, ScalarType & dmin, ScalarType & dmax) {
|
|
||||||
const CoordType dc = ClassType::Abs(p - n->boxCenter);
|
|
||||||
dmax = (dc + n->boxHalfDims).SquaredNorm();
|
|
||||||
dmin = ClassType::LowerClamp(dc - n->boxHalfDims, (ScalarType)0).SquaredNorm();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace vcg
|
|
||||||
|
|
||||||
#endif // #ifndef __VCGLIB_AABBBINARYTREESEARCH
|
|
|
@ -1,228 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
* VCGLib o o *
|
|
||||||
* Visual and Computer Graphics Library o o *
|
|
||||||
* _ O _ *
|
|
||||||
* Copyright(C) 2005 \/)\/ *
|
|
||||||
* 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 $
|
|
||||||
Revision 1.3 2005/09/16 10:03:46 m_di_benedetto
|
|
||||||
General interface redefinition, added special functors for faces.
|
|
||||||
|
|
||||||
Revision 1.2 2005/09/11 11:46:43 m_di_benedetto
|
|
||||||
First Commit
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __VCGLIB_AABBBINARYTREEUTILS
|
|
||||||
#define __VCGLIB_AABBBINARYTREEUTILS
|
|
||||||
|
|
||||||
// vcg headers
|
|
||||||
#include <vcg/space/point3.h>
|
|
||||||
#include <vcg/space/box3.h>
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************************/
|
|
||||||
|
|
||||||
namespace vcg {
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
Class AABBBinaryTreeUtils
|
|
||||||
|
|
||||||
SAMPLE USAGE:
|
|
||||||
|
|
||||||
NOTES:
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
template <class SCALARTYPE, class OBJTYPE>
|
|
||||||
class AABBBinaryTreeUtils {
|
|
||||||
public:
|
|
||||||
typedef AABBBinaryTreeUtils<SCALARTYPE, OBJTYPE> ClassType;
|
|
||||||
typedef SCALARTYPE ScalarType;
|
|
||||||
typedef OBJTYPE ObjType;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
template <class T1, class T2>
|
|
||||||
class P3Converter {
|
|
||||||
public:
|
|
||||||
static Point3<T1> Convert(const Point3<T2> & p) {
|
|
||||||
return Point3<T1>( (T1)p[0], (T1)p[1], (T1)p[2] );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
class P3Converter<T, T> {
|
|
||||||
public:
|
|
||||||
static Point3<T> Convert(const Point3<T> & p) {
|
|
||||||
return (p);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
template <class S, class T>
|
|
||||||
static Point3<S> ConvertP3(const Point3<T> & p) {
|
|
||||||
return (ClassType::P3Converter<S, T>::Convert(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
class Face {
|
|
||||||
};
|
|
||||||
|
|
||||||
class EmptyClass {
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ObjIteratorPtrFunct {
|
|
||||||
public:
|
|
||||||
template <class T>
|
|
||||||
inline T * operator () (T & t) {
|
|
||||||
return (&t);
|
|
||||||
}
|
|
||||||
template <class T *>
|
|
||||||
inline T * operator () (T* & t) {
|
|
||||||
return (t);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
static ObjIteratorPtrFunct IteratorPtrFunctor(void) {
|
|
||||||
ObjIteratorPtrFunct pp;
|
|
||||||
return pp;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OBJ>
|
|
||||||
class ObjBoxFunct {
|
|
||||||
public:
|
|
||||||
inline Box3<ScalarType> operator () (const OBJ & obj) {
|
|
||||||
(void)obj;
|
|
||||||
Box3<ScalarType> box;
|
|
||||||
box.SetNull();
|
|
||||||
return (box);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static ObjBoxFunct<ObjType> BoxFunctor(void) {
|
|
||||||
ObjBoxFunct<ObjType> tt;
|
|
||||||
return tt;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class FACETYPE>
|
|
||||||
class FaceBoxFunct {
|
|
||||||
public:
|
|
||||||
typedef FACETYPE FaceType;
|
|
||||||
inline Box3<ScalarType> operator () (const FaceType & f) {
|
|
||||||
Box3<ScalarType> box;
|
|
||||||
box.Set(ConvertP3<ScalarType, FaceType::ScalarType>(f.P(0)));
|
|
||||||
box.Add(ConvertP3<ScalarType, FaceType::ScalarType>(f.P(1)));
|
|
||||||
box.Add(ConvertP3<ScalarType, FaceType::ScalarType>(f.P(2)));
|
|
||||||
return (box);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class FACETYPE>
|
|
||||||
static FaceBoxFunct<FACETYPE> FaceBoxFunctor(void) {
|
|
||||||
FaceBoxFunct<FACETYPE> tt;
|
|
||||||
return tt;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OBJ>
|
|
||||||
class ObjBarycenterFunct {
|
|
||||||
public:
|
|
||||||
inline Point3<ScalarType> operator () (const OBJ & obj) {
|
|
||||||
(void)obj;
|
|
||||||
printf("GENERAL\n");
|
|
||||||
Point3<ScalarType> bc(ScalarType(0), ScalarType(0), ScalarType(0));
|
|
||||||
return (bc);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static ObjBarycenterFunct<ObjType> BarycenterFunctor(void) {
|
|
||||||
ObjBarycenterFunct<ObjType> tt;
|
|
||||||
return tt;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class FACETYPE>
|
|
||||||
class FaceBarycenterFunct {
|
|
||||||
public:
|
|
||||||
typedef FACETYPE FaceType;
|
|
||||||
inline Point3<ScalarType> operator () (const FaceType & f) {
|
|
||||||
return (ConvertP3<ScalarType, FaceType::ScalarType>(f.Barycenter()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class FACETYPE>
|
|
||||||
static FaceBarycenterFunct<FACETYPE> FaceBarycenterFunctor(void) {
|
|
||||||
FaceBarycenterFunct<FACETYPE> tt;
|
|
||||||
return tt;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OBJ>
|
|
||||||
class ObjPointDistanceFunct {
|
|
||||||
public:
|
|
||||||
inline bool operator () (const OBJ & obj, const Point3<ScalarType> & p, ScalarType & minDist, Point3<ScalarType> & res) {
|
|
||||||
(void)obj;
|
|
||||||
(void)p;
|
|
||||||
(void)minDist;
|
|
||||||
(void)res;
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static ObjPointDistanceFunct<ObjType> PointDistanceFunctor(void) {
|
|
||||||
ObjPointDistanceFunct<ObjType> tt;
|
|
||||||
return tt;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class FACETYPE>
|
|
||||||
class FacePointDistanceFunct {
|
|
||||||
public:
|
|
||||||
typedef FACETYPE FaceType;
|
|
||||||
inline bool operator () (const FaceType & f, const Point3<ScalarType> & p, ScalarType & minDist, Point3<ScalarType> & res) {
|
|
||||||
Point3<ScalarType> fp = ConvertP3<FaceType::ScalarType, ScalarType>(p);
|
|
||||||
typename FaceType::ScalarType md = (typename FaceType::ScalarType)minDist;
|
|
||||||
Point3<ScalarType> fres;
|
|
||||||
const bool bret = face::PointDistance(f, p, md, fres);
|
|
||||||
minDist = ScalarType(md);
|
|
||||||
res = ConvertP3<ScalarType, typename FaceType::ScalarType>(fres);
|
|
||||||
return (bret);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class FACETYPE>
|
|
||||||
static FacePointDistanceFunct<FACETYPE> FacePointDistanceFunctor(void) {
|
|
||||||
FacePointDistanceFunct<FACETYPE> tt;
|
|
||||||
return tt;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************************/
|
|
||||||
|
|
||||||
} // end namespace vcg
|
|
||||||
|
|
||||||
#endif // #ifndef __VCGLIB_AABBBINARYTREEUTILS
|
|
Loading…
Reference in New Issue