minor changes to comply gcc compiler

This commit is contained in:
Paolo Cignoni 2006-10-16 16:10:22 +00:00
parent 947b27d691
commit 5e4f12f28a
3 changed files with 244 additions and 222 deletions

View File

@ -34,6 +34,7 @@
#include <vcg/space/index/octree_template.h>
#include <vcg/space/box3.h>
#include <wrap/callback.h>
#include <wrap/gl/space.h>
namespace vcg
{
@ -104,13 +105,32 @@ namespace vcg
template < class OBJECT_TYPE, class SCALAR_TYPE>
class Octree : public vcg::OctreeTemplate< Voxel, SCALAR_TYPE >, public vcg::SpatialIndex< OBJECT_TYPE, SCALAR_TYPE >
{
public:
protected:
struct Neighbour;
public:
typedef SCALAR_TYPE ScalarType;
typedef OBJECT_TYPE ObjectType;
typedef typename Octree::Leaf * LeafPointer;
typedef typename Octree::InnerNode * InnerNodePointer;
typedef typename ReferenceType<OBJECT_TYPE>::Type * ObjectPointer;
typedef vcg::Voxel VoxelType;
typedef VoxelType * VoxelPointer;
typedef vcg::OctreeTemplate< VoxelType, SCALAR_TYPE > TemplatedOctree;
typedef typename TemplatedOctree::ZOrderType ZOrderType;
typedef typename TemplatedOctree::BoundingBoxType BoundingBoxType;
typedef typename TemplatedOctree::CenterType CenterType;
typedef typename TemplatedOctree::CoordinateType CoordType;
typedef typename TemplatedOctree::NodeType NodeType;
typedef typename TemplatedOctree::NodePointer NodePointer;
typedef typename TemplatedOctree::NodeIndex NodeIndex;
typedef typename std::vector< Neighbour >::iterator NeighbourIterator;
/*!
* Structure which holds the rendering settings
*/
@ -130,10 +150,6 @@ namespace vcg
vcg::Color4b color;
};
protected:
/***********************************************
* INNER DATA STRUCTURES AND PREDICATES *
@ -148,11 +164,11 @@ namespace vcg
ObjectPlaceholder() { z_order = object_index = -1, leaf_pointer = NULL;}
ObjectPlaceholder(ZOrderType z_order, void* leaf_pointer, unsigned int object_index)
ObjectPlaceholder(ZOrderType zOrder, void* leafPointer, unsigned int objectIndex)
{
this->z_order = z_order;
this->leaf_pointer = leaf_pointer;
this->object_index = object_index;
z_order = zOrder;
leaf_pointer = leafPointer;
object_index = objectIndex;
}
ZOrderType z_order;
@ -201,6 +217,11 @@ namespace vcg
this->point = point;
this->distance = distance;
}
inline bool operator<(const Neighbour &n)
{
return distance<n.distance;
}
ObjectPointer object;
@ -208,13 +229,13 @@ namespace vcg
ScalarType distance;
};
/*
* The operator used for sorting the items in neighbors based on the distances
*/
struct DistanceCompare
{
inline bool operator()( const Neighbour &p1, const Neighbour &p2) const { return p1.distance<p2.distance; }
}; //end of DistanceCompare
// /*
// * The operator used for sorting the items in neighbors based on the distances
// */
// struct DistanceCompare
// {
// inline bool operator()( const Neighbour &p1, const Neighbour &p2) const { return p1.distance<p2.distance; }
// }; //end of DistanceCompare
@ -222,18 +243,18 @@ public:
~Octree()
{
delete []marks;
int node_count = NodeCount();
int node_count = TemplatedOctree::NodeCount();
for (int i=0; i<node_count; i++)
delete nodes[i];
nodes.clear();
delete TemplatedOctree::nodes[i];
TemplatedOctree::nodes.clear();
}
/*!
* Populate the octree
*/
template <class OBJECT_ITERATOR/*, class BOUNDING_BOX_FUNCTOR*/>
void Set(const OBJECT_ITERATOR & bObj, const OBJECT_ITERATOR & eObj /*, const BoundingBoxType &bounding_box*/ /*, const BOUNDING_BOX_FUNCTOR &bb_functor*/ /*, vcg::CallBackPos *callback=NULL*/)
template < class OBJECT_ITERATOR >
void Set(const OBJECT_ITERATOR & bObj, const OBJECT_ITERATOR & eObj /*, vcg::CallBackPos *callback=NULL*/)
{
// Compute the bounding-box enclosing the whole dataset
typedef Dereferencer<typename ReferenceType<typename OBJECT_ITERATOR::value_type>::Type > DereferencerType;
@ -253,7 +274,7 @@ public:
ScalarType longest_side = vcg::math::Max( resulting_bb.DimX(), vcg::math::Max(resulting_bb.DimY(), resulting_bb.DimZ()) )/2.0f;
resulting_bb.Set(center);
resulting_bb.Offset(longest_side);
boundingBox = resulting_bb;
TemplatedOctree::boundingBox = resulting_bb;
// Try to find a reasonable octree depth
int dataset_dimension = std::distance(bObj, eObj);
@ -268,16 +289,16 @@ public:
depth++;
}
while (primitives_per_voxel>25 && depth<15);
Initialize(++depth);
TemplatedOctree::Initialize(++depth);
// Sort the dataset (using the lebesgue space filling curve...)
std::string message("Indexing dataset...");
Octree::NodePointer *route = new Octree::NodePointer[depth+1];
NodePointer *route = new NodePointer[depth+1];
OBJECT_ITERATOR iObj = bObj;
//if (callback!=NULL) callback(int((i+1)*100/dataset_dimension), message.c_str());
std::vector< ObjectPlaceholder< Octree::Node > > placeholders/*(dataset_dimension)*/;
std::vector< ObjectPlaceholder< NodeType > > placeholders/*(dataset_dimension)*/;
vcg::Box3<ScalarType> object_bb;
vcg::Point3<ScalarType> hit_leaf;
for (int i=0; i<dataset_dimension; i++, iObj++)
@ -288,20 +309,20 @@ public:
while (object_bb.IsIn(hit_leaf))
{
int placeholder_index = placeholders.size();
placeholders.push_back( ObjectPlaceholder< Octree::Node >() );
placeholders.push_back( ObjectPlaceholder< NodeType >() );
placeholders[placeholder_index].z_order = BuildRoute(hit_leaf, route);
placeholders[placeholder_index].leaf_pointer = route[depth];
placeholders[placeholder_index].object_index = i;
hit_leaf.X() += leafDimension.X();
hit_leaf.X() += TemplatedOctree::leafDimension.X();
if (hit_leaf.X()>object_bb.max.X())
{
hit_leaf.X() = object_bb.min.X();
hit_leaf.Z()+= leafDimension.Z();
hit_leaf.Z()+= TemplatedOctree::leafDimension.Z();
if (hit_leaf.Z()>object_bb.max.Z())
{
hit_leaf.Z() = object_bb.min.Z();
hit_leaf.Y()+= leafDimension.Y();
hit_leaf.Y()+= TemplatedOctree::leafDimension.Y();
}
}
}
@ -315,8 +336,8 @@ public:
marks = new unsigned char[placeholder_count];
memset(&marks[0], 0, sizeof(unsigned char)*placeholder_count);
std::sort(placeholders.begin(), placeholders.end(), ObjectSorter< Octree::Node >());
std::vector< Octree::Node* > filled_leaves(placeholder_count);
std::sort(placeholders.begin(), placeholders.end(), ObjectSorter< NodeType >());
std::vector< NodePointer > filled_leaves(placeholder_count);
sorted_dataset.resize( placeholder_count );
for (int i=0; i<placeholder_count; i++)
{
@ -337,13 +358,13 @@ public:
do end++;
while (end<placeholder_count && initial_leaf==filled_leaves[end]);
VoxelType *voxel = Voxel(initial_leaf);
VoxelType *voxel = TemplatedOctree::Voxel(initial_leaf);
voxel->SetRange(begin, end);
}
// The octree is built, the dataset is sorted but only the leaves are indexed:
// we propaget the indexing information bottom-up to the root
IndexInnerNodes( Root() );
IndexInnerNodes( TemplatedOctree::Root() );
} //end of Set
/*!
@ -370,7 +391,7 @@ public:
unsigned int object_count;
int leaves_count;
ScalarType k_distance = leafDiagonal;
ScalarType k_distance = TemplatedOctree::leafDiagonal;
IncrementMark();
@ -379,14 +400,14 @@ public:
leaves.clear();
object_count = 0;
query_bb.Offset(k_distance);
sphere_radius += vcg::math::Max<ScalarType>(leafDiagonal, k_distance);
sphere_radius += vcg::math::Max<ScalarType>(TemplatedOctree::leafDiagonal, k_distance);
ContainedLeaves(query_bb, leaves, Root(), boundingBox);
ContainedLeaves(query_bb, leaves, TemplatedOctree::Root(), TemplatedOctree::boundingBox);
leaves_count = int(leaves.size());
object_count = 0;
for (int i=0; i<leaves_count; i++)
object_count += Voxel( leaves[i] )->count;
object_count += TemplatedOctree::Voxel( leaves[i] )->count;
}
while (object_count==0 && sphere_radius<max_distance);
@ -426,9 +447,9 @@ public:
} // end of for (int i=0; i<leavesCount; i++)
object_count = int(neighbors.size());
std::vector< Neighbour >::iterator first = neighbors.begin();
std::vector< Neighbour >::iterator last = neighbors.end();
std::partial_sort(first, first+object_count, last, DistanceCompare());
typename std::vector< Neighbour >::iterator first = neighbors.begin();
typename std::vector< Neighbour >::iterator last = neighbors.end();
std::partial_sort< Neighbour >(first, first+object_count, last/*, DistanceCompare()*/);
distance = neighbors[0].distance;
point = neighbors[0].point;
return neighbors[0].object;
@ -442,14 +463,14 @@ public:
(
OBJECT_POINT_DISTANCE_FUNCTOR & distance_functor,
OBJECT_MARKER & /*marker*/,
const unsigned int k,
unsigned int k,
const CoordType & query_point,
const ScalarType & max_distance,
OBJECT_POINTER_CONTAINER & objects,
DISTANCE_CONTAINER & distances,
POINT_CONTAINER & points,
bool sort_per_distance = false,
bool allow_zero_distance = false
bool sort_per_distance = true,
bool allow_zero_distance = true
)
{
BoundingBoxType query_bb;
@ -462,7 +483,7 @@ public:
unsigned int object_count;
int leaves_count;
float k_distance = leafDiagonal;
float k_distance = TemplatedOctree::leafDiagonal;
do
{
IncrementMark();
@ -472,14 +493,14 @@ public:
leaves.clear();
object_count = 0;
query_bb.Offset(k_distance);
sphere_radius += vcg::math::Max<float>(leafDiagonal, k_distance);
sphere_radius += vcg::math::Max<float>(TemplatedOctree::leafDiagonal, k_distance);
ContainedLeaves(query_bb, leaves, Root(), boundingBox);
ContainedLeaves(query_bb, leaves, TemplatedOctree::Root(), TemplatedOctree::boundingBox);
leaves_count = int(leaves.size());
object_count = 0;
for (int i=0; i<leaves_count; i++)
object_count += Voxel( leaves[i] )->count;
object_count += TemplatedOctree::Voxel( leaves[i] )->count;
}
while (object_count<k && sphere_radius<max_distance); // TODO check the termination condintion
@ -529,11 +550,11 @@ public:
else
object_count=int(neighbors.size());
std::vector< Neighbour >::iterator first = neighbors.begin();
std::vector< Neighbour >::iterator last = neighbors.end();
NeighbourIterator first = neighbors.begin();
NeighbourIterator last = neighbors.end();
if (sort_per_distance) std::partial_sort(first, first+object_count, last, DistanceCompare());
else std::nth_element (first, first+object_count, last, DistanceCompare());
if (sort_per_distance) std::partial_sort< NeighbourIterator >(first, first+object_count, last /*, DistanceCompare()*/ );
else std::nth_element < NeighbourIterator >(first, first+object_count, last /*, DistanceCompare()*/ );
k_distance = neighbors[object_count-1].distance;
}
while (k_distance>sphere_radius && sphere_radius<max_distance);
@ -563,19 +584,19 @@ public:
BoundingBoxType query_bb(sphere_center, sphere_radius);
// If that bounding-box don't collide with the octree bounding-box, simply return 0
if (!boundingBox.Collide(query_bb))
if (!TemplatedOctree::boundingBox.Collide(query_bb))
return 0;
std::vector< NodePointer > leaves;
std::vector< Neighbour > neighbors;
unsigned int object_count = 0;
float k_distance = leafDiagonal;
//float k_distance = TemplatedOctree::leafDiagonal;
IncrementMark();
ContainedLeaves(query_bb, leaves, Root(), boundingBox);
ContainedLeaves(query_bb, leaves, TemplatedOctree::Root(), TemplatedOctree::boundingBox);
int leaves_countleaves_count = int(leaves.size());
int leaves_count = int(leaves.size());
if (leaves_count==0)
return 0;
@ -597,20 +618,20 @@ public:
continue;
distance = sphere_radius;
if (!distance_functor(*ref->pObject, query_point, distance, closest_point))
if (!distance_functor(*ref->pObject, sphere_center, distance, closest_point))
continue;
object_count++;
Mark(ref);
if ((distance!=0.0f || allow_zero_distance) && distance<max_distance)
if ((distance!=0.0f || allow_zero_distance) && distance<sphere_radius)
neighbors.push_back( Neighbour(ref->pObject, closest_point, distance) );
} //end of for ( ; begin<end; begin++)
} // end of for (int i=0; i<leavesCount; i++)
std::vector< Neighbour >::iterator first = neighbors.begin();
std::vector< Neighbour >::iterator last = neighbors.end();
if (sort_per_distance) std::partial_sort(first, first+object_count, last, DistanceCompare());
else std::nth_element (first, first+object_count, last, DistanceCompare());
NeighbourIterator first = neighbors.begin();
NeighbourIterator last = neighbors.end();
if (sort_per_distance) std::partial_sort< NeighbourIterator >(first, first+object_count, last /*, DistanceCompare()*/ );
else std::nth_element < NeighbourIterator >(first, first+object_count, last /*, DistanceCompare()*/ );
return CopyQueryResults<OBJECT_POINTER_CONTAINER, DISTANCE_CONTAINER, POINT_CONTAINER>(neighbors, object_count, objects, distances, points);
};//end of GetInSphere
@ -638,7 +659,7 @@ public:
unsigned int object_count;
int leaves_count;
ContainedLeaves(query_bounding_box, leaves, Root(), boundingBox);
ContainedLeaves(query_bounding_box, leaves, TemplatedOctree::Root(), TemplatedOctree::boundingBox);
leaves_count = int(leaves.size());
if (leaves_count==0)
{
@ -684,7 +705,7 @@ public:
{
for (int s=0; s<8; s++)
if ((son=Son(n, s))!=0)
DrawOctree(SubBox(boundingBox, s), son);
DrawOctree(TemplatedOctree::SubBox(boundingBox, s), son);
}
else
{
@ -692,7 +713,7 @@ public:
if (level<rendering_settings.maxVisibleDepth)
for (int s=0; s<8; s++)
if ((son=Son(n, s))!=0)
DrawOctree(SubBox(boundingBox, s), son);
DrawOctree(TemplatedOctree::SubBox(boundingBox, s), son);
}
};
@ -755,10 +776,10 @@ public:
{
do
{
query_bb.Offset(leafDiagonal);
sphere_radius += leafDiagonal;
query_bb.Offset(TemplatedOctree::leafDiagonal);
sphere_radius += TemplatedOctree::leafDiagonal;
}
while ( !boundingBox.Collide(query_bb) || sphere_radius>max_distance); // TODO check the termination condintion
while ( !TemplatedOctree::boundingBox.Collide(query_bb) || sphere_radius>max_distance); // TODO check the termination condintion
}
return (sphere_radius<=max_distance);
};
@ -784,9 +805,9 @@ public:
objects.resize(object_count);
}
POINT_CONTAINER::iterator iPoint = points.begin();
DISTANCE_CONTAINER::iterator iDistance = distances.begin();
OBJECT_POINTER_CONTAINER::iterator iObject = objects.begin();
typename POINT_CONTAINER::iterator iPoint = points.begin();
typename DISTANCE_CONTAINER::iterator iDistance = distances.begin();
typename OBJECT_POINTER_CONTAINER::iterator iObject = objects.begin();
for (unsigned int n=0; n<object_count; n++, iPoint++, iDistance++, iObject++)
{
(*iPoint) = neighbors[n].point;
@ -803,24 +824,22 @@ public:
{
assert(n!=NULL);
VoxelPointer current_voxel = Voxel(n);
VoxelPointer current_voxel = TemplatedOctree::Voxel(n);
VoxelPointer son_voxel;
for (int s=0; s<8; s++)
{
NodePointer son_index = Son(n, s);
if (son_index!=NULL)
{
if (Level(son_index)!=maximumDepth)
if (Level(son_index)!=TemplatedOctree::maximumDepth)
IndexInnerNodes(son_index);
son_voxel = Voxel(son_index);
son_voxel = TemplatedOctree::Voxel(son_index);
current_voxel->AddRange( son_voxel );
}
}
}; // end of IndexInnerNodes
};
} //end of namespace vcg
#endif //VCG_SPACE_INDEX_OCTREE_H

View File

@ -8,7 +8,7 @@
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* 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. *
@ -58,13 +58,14 @@ public:
// Octree Type Definitions
typedef unsigned long long ZOrderType;
typedef SCALAR_TYPE ScalarType;
typedef typename VOXEL_TYPE VoxelType;
typedef typename VOXEL_TYPE *VoxelPointer;
typedef vcg::Point3i CenterType;
typedef VOXEL_TYPE VoxelType;
typedef VoxelType * VoxelPointer;
typedef vcg::Point3i CenterType;
static const ScalarType EXPANSION_FACTOR;
typedef Node NodeType;
typedef int NodeIndex;
typedef Node *NodePointer;
typedef vcg::Box3<ScalarType> BoundingBoxType;
typedef NodeType * NodePointer;
typedef vcg::Box3<ScalarType> BoundingBoxType;
typedef vcg::Point3<ScalarType> CoordinateType;
protected:
@ -94,19 +95,19 @@ protected:
// The position of the center of the node in integer coords in the 0..2^(2*sz) -1 range
// The root has position (lsz/2,lsz/2,lsz/2)
CenterType center;
char level;
CenterType center;
char level;
NodePointer parent;
VoxelType voxel;
};
/*
* Inner struct: Node
* Inner struct: Node
*/
struct InnerNode : public Node
{
InnerNode() : Node() {};
InnerNode(NodePointer parent, int level) : Node(parent, level)
InnerNode(NodePointer parent, int level) : Node(parent, level)
{
memset(&sons[0], NULL, 8*sizeof(Node*));
}
@ -136,7 +137,8 @@ protected:
inline NodePointer &Son(int /*sonIndex*/)
{
assert(false);
return parent;
NodePointer p = NULL;
return p;
}
inline bool IsLeaf()
@ -152,12 +154,12 @@ public:
this->maximumDepth = maximumDepth;
size = 1<< maximumDepth; // e.g. 1*2^maxDepth
lSize = 1<<(maximumDepth+1); // e.g. 1*2^(maxDepth+1)
InnerNode *root = new InnerNode(NULL,0);
nodes.clear();
nodes.push_back( root );
root->center = CenterType(size, size, size);
ScalarType szf = (ScalarType) size;
leafDimension = boundingBox.Dim();
leafDimension /= szf;
@ -166,7 +168,7 @@ public:
// Return the octree bounding-box
inline BoundingBoxType BoundingBox() { return boundingBox; }
// Return the Voxel of the n-th node
inline VoxelPointer Voxel(const NodePointer n) { return &(n->voxel); }
@ -188,20 +190,20 @@ public:
// Return the index of the current node in its father
int WhatSon(NodePointer n) const
{
if(n==Root())
if(n==Root())
assert(false);
NodePointer parent = Parent(n);
for(int i=0;i<8;++i)
if(parent->Son(i)==n)
if(parent->Son(i)==n)
return i;
return -1;
}
// Return the center of the n-th node
// Return the center of the n-th node
inline CenterType CenterInOctreeCoordinates(const NodePointer n) const { return n->center;}
/*!
* Return the center of the n-th node expressed in world-coordinate
* \param NodePointer the pointer to the node whose center in world coordinate has to be computed
@ -210,12 +212,12 @@ public:
{
assert(0<=n && n<NodeCount());
int shift = maximumDepth - n->level + 1;
int shift = maximumDepth - Level(n) + 1;
CoordinateType ocCenter = CenterInOctreeCoordinates(n);
CoordinateType nodeSize = boundingBox.Dim()/float(1<<level);
wcCenter.X() = boundingBox.min.X() + (nodeSize.X()*(0.5f+(ocCenter.X()>>shift)));
wcCenter.Y() = boundingBox.min.Y() + (nodeSize.Y()*(0.5f+(ocCenter.Y()>>shift)));
wcCenter.Z() = boundingBox.min.Z() + (nodeSize.Z()*(0.5f+(ocCenter.Z()>>shift)));
CoordinateType nodeSize = boundingBox.Dim()/float(1<<Level(n));
wc_Center.X() = boundingBox.min.X() + (nodeSize.X()*(0.5f+(ocCenter.X()>>shift)));
wc_Center.Y() = boundingBox.min.Y() + (nodeSize.Y()*(0.5f+(ocCenter.Y()>>shift)));
wc_Center.Z() = boundingBox.min.Z() + (nodeSize.Z()*(0.5f+(ocCenter.Z()>>shift)));
};
// Given a node (even not leaf) it returns the center of the box it represent.
@ -238,30 +240,30 @@ public:
a) a leaf at the deepest level 2 has position (.5,.5)
b) a mid node (lev 1) has position (1,1)
c) root has level 0 and position (sz/2,sz/2) = (2,2)
c) root has level 0 and position (sz/2,sz/2) = (2,2)
The center of a node has integer coords in the 2^(MaxDepth+1) range.
The other approach is to use position as a bit string
codifying the tree path, but in this case you have to
supply also the level (e.g. the string lenght)
The other approach is to use position as a bit string
codifying the tree path, but in this case you have to
supply also the level (e.g. the string lenght)
you desire. The lower left corner node is always 0 ( (,) for the root (0,0) level 1, and (00,00) for level 2)
| ~~~ |
| 0~~ | 1~~ |
| 00~ | 01~ | 10~ | 11~ |
|000|001|010|011|100|101|110|111|
|000|001|010|011|100|101|110|111|
The interesting properties is that
if your octree represent a space [minv,maxv] and you want
to find the octree cell containing a point p in [minv,maxv]
if your octree represent a space [minv,maxv] and you want
to find the octree cell containing a point p in [minv,maxv]
you just have to convert p in the range [0,sz) truncate it to an integer and use it as a path.
For example, consider an octree of depth 3, representing a range [0..100)
sz=8 (each cell contains form 0 to 12.5
the point
the point
5 -> 0.4 -> path is 000
45 -> 3.6 -> path is 011
50 -> 4.0 -> path is 100
45 -> 3.6 -> path is 011
50 -> 4.0 -> path is 100
100 -> 8 -> ERROR the interval is right open!!!
Note how each cell is meant to contains a right open interval (e.g. the first cell contains [0,12.5) and the second [12.5,25) and so on)
@ -321,21 +323,21 @@ public:
else bs.max.Y()=((bs.min.Y()=lbb.min.Y())+lbb.max.Y())/2.0f;
if (i&4) bs.min.Z()=(lbb.min.Z()+(bs.max.Z()=lbb.max.Z()))/2.0f;
else bs.max.Z()=((bs.min.Z()=lbb.min.Z())+lbb.max.Z())/2.0f;
return bs;
}
// Given the bounding-box and the center (both in world-coordinates)
// of a node, return the bounding-box (in world-coordinats) of the i-th son
// of a node, return the bounding-box (in world-coordinats) of the i-th son
BoundingBoxType SubBoxAndCenterInWorldCoordinates(BoundingBoxType &lbb, CoordinateType &center, int i)
{
BoundingBoxType bs;
if (i&1)
if (i&1)
{
bs.min[0]=center[0];
bs.max[0]=lbb.max[0];
}
else
else
{
bs.min[0]=lbb.min[0];
bs.max[0]=center[0];
@ -345,17 +347,17 @@ public:
bs.min[1]=center[1];
bs.max[1]=lbb.max[1];
}
else
else
{
bs.max[1]=center[1];
bs.min[1]=lbb.min[1];
}
if (i&4)
if (i&4)
{
bs.min[2]=center[2];
bs.max[2]=lbb.max[2];
}
else
else
{
bs.max[2]=center[2];
bs.min[2]=lbb.min[2];
@ -364,7 +366,7 @@ public:
};
/*
* Add a new Node to the octree.
* Add a new Node to the octree.
* The created node is the i-th son of the node pointed to by parent.
* Return the pointer to the new node
*/
@ -375,11 +377,11 @@ public:
//int index = NodeCount();
char level = Level(parent)+1;
Node *node = (level<maximumDepth)? (Node*) new InnerNode(parent, level) : (Node*) new Leaf(parent, level);
nodes.push_back( node );
Son(parent, i) = node;
CenterType *parentCenter = &(parent->center);
int displacement = 1<<(maximumDepth-level);
node->center.X() = parentCenter->X() + ((i&1)? displacement : -displacement);
@ -395,24 +397,24 @@ public:
NodePointer AddNode(CenterType path)
{
//the input coordinates must be in the range 0..2^maxdepth
assert(path[0]>=0 && path[0]<size);
assert(path[1]>=0 && path[1]<size);
assert(path[0]>=0 && path[0]<size);
assert(path[1]>=0 && path[1]<size);
assert(path[2]>=0 && path[2]<size);
NodePointer curNode = Root();
int rootLevel = 0;
int shiftLevel = maximumDepth-1;
while(shiftLevel >= rootLevel)
{
int nextSon=0;
if((path[0]>>shiftLevel)%2) nextSon +=1;
if((path[1]>>shiftLevel)%2) nextSon +=2;
if((path[2]>>shiftLevel)%2) nextSon +=4;
NodePointer nextNode = Son(curNode, nextSon);
if(nextNode!=NULL) // nessun nodo può aver Root() per figlio
if((path[0]>>shiftLevel)%2) nextSon +=1;
if((path[1]>>shiftLevel)%2) nextSon +=2;
if((path[2]>>shiftLevel)%2) nextSon +=4;
NodePointer nextNode = Son(curNode, nextSon);
if(nextNode!=NULL) // nessun nodo può aver Root() per figlio
curNode = nextNode;
else
else
{
NodePointer newNode = NewNode(curNode, nextSon);
assert(Son(curNode, nextSon)==newNode); // TODO delete an assignment
@ -427,9 +429,9 @@ public:
* Given a query point, compute the z_order of the leaf where this point would be contained.
* This leaf not necessarily must be exist!
*/
// Convert the point p coordinates to the integer based representation
// Convert the point p coordinates to the integer based representation
// in the range 0..size, where size is 2^maxdepth
CenterType Interize(const CoordinateType &pf) const
CenterType Interize(const CoordinateType &pf) const
{
CenterType pi;
@ -440,29 +442,29 @@ public:
pi.X() = int((pf.X() - boundingBox.min.X()) * size / (boundingBox.max.X() - boundingBox.min.X()));
pi.Y() = int((pf.Y() - boundingBox.min.Y()) * size / (boundingBox.max.Y() - boundingBox.min.Y()));
pi.Z() = int((pf.Z() - boundingBox.min.Z()) * size / (boundingBox.max.Z() - boundingBox.min.Z()));
return pi;
}
// Inverse function of Interize;
// Inverse function of Interize;
// Return to the original coords space (not to the original values!!)
CoordinateType DeInterize(const CenterType &pi ) const
CoordinateType DeInterize(const CenterType &pi ) const
{
CoordinateType pf;
assert(pi.X()>=0 && pi.X()<size);
assert(pi.Y()>=0 && pi.Y()<size);
assert(pi.Z()>=0 && pi.Z()<size);
assert(pi.X()>=0 && pi.X()<size);
assert(pi.Y()>=0 && pi.Y()<size);
assert(pi.Z()>=0 && pi.Z()<size);
pf.X() = pi.X() * (boundingBox.max.X() - boundingBox.min.X()) / size + boundingBox.min.X();
pf.Y() = pi.Y() * (boundingBox.max.Y() - boundingBox.min.Y()) / size + boundingBox.min.Y();
pf.Z() = pi.Z() * (boundingBox.max.Z() - boundingBox.min.Z()) / size + boundingBox.min.Z();
pf.X() = vi.X() * (boundingBox.max.X() - boundingBox.min.X()) / size + boundingBox.min.X();
pf.Y() = vi.Y() * (boundingBox.max.Y() - boundingBox.min.Y()) / size + boundingBox.min.Y();
pf.Z() = vi.Z() * (boundingBox.max.Z() - boundingBox.min.Z()) / size + boundingBox.min.Z();
return pf;
}
// Compute the z-ordering integer value for a given node;
// this value can be used to compute a complete ordering of the nodes of a given level of the octree.
// this value can be used to compute a complete ordering of the nodes of a given level of the octree.
// It assumes that the octree has a max depth of 10.
ZOrderType ZOrder(NodePointer n) const { return ZOrder(GetPath(n), Level(n)); }
ZOrderType ComputeZOrder(const CoordinateType &query) const { return ZOrder(CenterType::Construct(Interize(query)), maximumDepth); };
@ -471,7 +473,7 @@ public:
{
ZOrderType finalPosition = 0;
ZOrderType currentPosition;
for(int i=0; i<level; ++i)
{
currentPosition = 0;
@ -485,33 +487,33 @@ public:
return finalPosition;
};
// Funzione principale di accesso secondo un path;
// restituisce l'indice del voxel di profondita' massima
// che contiene il punto espresso in range 0..2^maxk
// Funzione principale di accesso secondo un path;
// restituisce l'indice del voxel di profondita' massima
// che contiene il punto espresso in range 0..2^maxk
NodePointer DeepestNode(CenterType path, int MaxLev)
{
assert(path[0]>=0 && path[0]<sz);
assert(path[1]>=0 && path[1]<sz);
assert(path[2]>=0 && path[2]<sz);
assert(path[0]>=0 && path[0]<size);
assert(path[1]>=0 && path[1]<size);
assert(path[2]>=0 && path[2]<size);
NodePointer curNode = Root();
int shift = maximumDepth-1;
while(shift && Level(curNode) < MaxLev)
{
int son = 0;
if((path[0]>>shift)%2) son +=1;
if((path[1]>>shift)%2) son +=2;
if((path[2]>>shift)%2) son +=4;
if((path[0]>>shift)%2) son +=1;
if((path[1]>>shift)%2) son +=2;
if((path[2]>>shift)%2) son +=4;
NodePointer nextNode = Son(curNode, son);
if(nextNode!=NULL)
CurNode=nextNode;
else
if(nextNode!=NULL)
curNode=nextNode;
else
break;
--shift;
}
return CurNode;
return curNode;
}
@ -522,9 +524,9 @@ public:
// for the first level only one bit of each one of the three components are maninguful;
CenterType GetPath(NodePointer n) const
{
if(n==Root())
if(n==Root())
return CenterType(0,0,0);
CenterType path(0,0,0);
int shift, mask, son;
@ -538,13 +540,13 @@ public:
if(son&2) path[1] |= mask;
if(son&4) path[2] |= mask;
n = Parent(n); // nodes[n].parent
}
}
return path;
}
// Dato un punto 3D nello spazio restituisce un array contenente
// i puntatori ai nodi che lo contengono, dalla radice fino alle foglie.
// I nodi mancanti dalla radice fino a profondità maxDepth vengono aggiunti.
// Dato un punto 3D nello spazio restituisce un array contenente
// i puntatori ai nodi che lo contengono, dalla radice fino alle foglie.
// I nodi mancanti dalla radice fino a profondità maxDepth vengono aggiunti.
// In posizione i ci sarà il nodo di livello i.
// Restituisce lo z-order del punto p
ZOrderType BuildRoute(const CoordinateType &p, NodePointer *&route)
@ -560,9 +562,9 @@ public:
while(shift >= 0)
{
int son = 0;
if((path[0]>>shift)%2) son +=1;
if((path[1]>>shift)%2) son +=2;
if((path[2]>>shift)%2) son +=4;
if((path[0]>>shift)%2) son +=1;
if((path[1]>>shift)%2) son +=2;
if((path[2]>>shift)%2) son +=4;
NodePointer nextNode = Son(curNode, son);
if(nextNode!=NULL)
@ -570,7 +572,7 @@ public:
route[maximumDepth-shift] = nextNode;
curNode = nextNode;
}
else
else
{
NodePointer newNode = NewNode(curNode, son);
route[maximumDepth-shift] = newNode;
@ -594,43 +596,43 @@ public:
assert( boundingBox.min.Y()<=p.Y() && p.Y()<=boundingBox.max.Y() );
assert( boundingBox.min.Z()<=p.Z() && p.Z()<=boundingBox.max.Z() );
memset(route, NULL, maxDepth*sizeof(NodePointer));
memset(route, NULL, maximumDepth*sizeof(NodePointer));
CenterType path = CenterType::Construct(Interize(p));
int shift = maxDepth-1;
int shift = maximumDepth-1;
NodePointer finalLevel = Root();
NodePointer curNode = Root();
while(shift >= finalLevel)
{
int son=0;
if((path[0]>>shift)%2) son +=1;
if((path[1]>>shift)%2) son +=2;
if((path[2]>>shift)%2) son +=4;
NodePointer nextNode = Son(curNode, son);
if(nextNode!=NULL)
if((path[0]>>shift)%2) son +=1;
if((path[1]>>shift)%2) son +=2;
if((path[2]>>shift)%2) son +=4;
NodePointer nextNode = Son(curNode, son);
if(nextNode!=NULL)
{
route[maxDepth-shift] = nextNode;
route[maximumDepth-shift] = nextNode;
curNode = nextNode;
}
else
else
return false;
--shift;
}
return true;
}; //end of GetReoute
// Data una bounding-box bb_query, calcola l'insieme dei nodi di
// profondità depth il cui bounding-box ha intersezione non nulla con
// bb (la bounding-box dell'octree); i puntatori a tali nodi sono
// Data una bounding-box bb_query, calcola l'insieme dei nodi di
// profondità depth il cui bounding-box ha intersezione non nulla con
// bb (la bounding-box dell'octree); i puntatori a tali nodi sono
// inseriti progressivamente in contained_nodes.
// The vector nodes must be cleared before calling this method.
void ContainedNodes
(
BoundingBoxType &query,
std::vector< NodePointer > &nodes,
int depth,
int depth,
NodePointer n,
BoundingBoxType &nodeBB)
{
@ -655,13 +657,13 @@ public:
}
}
}; //end of ContainedNodes
// Data una bounding-box bb, calcola l'insieme delle foglie il cui
// Data una bounding-box bb, calcola l'insieme delle foglie il cui
// bounding-box ha intersezione non nulla con bb; i loro indici
// sono inseriti all'interno di leaves.
void ContainedLeaves(
BoundingBoxType &query,
BoundingBoxType &query,
std::vector< NodePointer > &leaves,
NodePointer node,
BoundingBoxType &nodeBB
@ -687,7 +689,7 @@ public:
}
}; //end of ContainedLeaves
/*
* Octree Data Members
*/
@ -702,11 +704,11 @@ public:
int maximumDepth;
// The dimension of a leaf
CoordinateType leafDimension;
CoordinateType leafDimension;
// The diagonal of a leaf
ScalarType leafDiagonal;
// The Octree nodes
std::vector< Node* > nodes;

View File

@ -47,23 +47,19 @@ namespace vcg
class NormalExtrapolation
{
public:
typedef typename VERTEX_CONTAINER::value_type VertexType;
typedef typename VertexType *VertexPointer;
typedef typename VERTEX_CONTAINER::iterator VertexIterator;
typedef typename VertexType::CoordType CoordType;
typedef typename VertexType::NormalType NormalType;
typedef typename VertexType::ScalarType ScalarType;
typedef typename vcg::Box3< ScalarType > BoundingBoxType;
typedef typename vcg::Matrix33<ScalarType> MatrixType;
typedef typename VERTEX_CONTAINER::value_type VertexType;
typedef VertexType * VertexPointer;
typedef typename VERTEX_CONTAINER::iterator VertexIterator;
typedef typename VertexType::CoordType CoordType;
typedef typename VertexType::NormalType NormalType;
typedef typename VertexType::ScalarType ScalarType;
typedef typename vcg::Box3< ScalarType > BoundingBoxType;
typedef typename vcg::Matrix33<ScalarType> MatrixType;
enum NormalOrientation {IsCorrect=0, MustBeFlipped=1};
public:
/*!
*/
static void ExtrapolateNormlas(const VertexIterator &begin, const VertexIterator &end, int k, const int root_index=-1, NormalOrientation orientation=IsCorrect, CallBackPos *callback=NULL)
{
/*************************************************
private:
/*************************************************
* Inner class definitions
**************************************************/
// Dummy class: no object marker is needed
@ -139,9 +135,14 @@ namespace vcg
std::vector< MSTNode* > sons;
};
/*************************************************
* The Algorithm
**************************************************/
typedef std::vector< Plane > PlaneContainer;
typedef typename PlaneContainer::iterator PlaneIterator;
public:
/*!
*/
static void ExtrapolateNormals(const VertexIterator &begin, const VertexIterator &end, const unsigned int k, const int root_index=-1, NormalOrientation orientation=IsCorrect, CallBackPos *callback=NULL)
{
BoundingBoxType dataset_bb;
for (VertexIterator iter=begin; iter!=end; iter++)
dataset_bb.Add(iter->P());
@ -156,7 +157,7 @@ namespace vcg
sprintf(message, "Locating tangent planes...");
std::vector< Plane > tangent_planes(vertex_count);
vcg::Octree< VertexType, ScalarType > octree_for_planes;
octree_for_planes.Set< VertexIterator >(begin, end);
octree_for_planes.Set( begin, end );
std::vector< VertexPointer > nearest_vertices;
std::vector< CoordType > nearest_points;
@ -165,8 +166,7 @@ namespace vcg
{
if (callback!=NULL && (++progress%step)==0 && (percentage=int((progress*100)/vertex_count))<100) (callback)(percentage, message);
octree_for_planes.GetKClosest<VertPointDistanceFunctor, DummyObjectMarker, std::vector<VertexPointer>, std::vector<ScalarType>, std::vector<CoordType> >
(VertPointDistanceFunctor(), DummyObjectMarker(), k, iter->P(), max_distance, nearest_vertices, distances, nearest_points);
octree_for_planes.GetKClosest(VertPointDistanceFunctor(), DummyObjectMarker(), k, iter->P(), max_distance, nearest_vertices, distances, nearest_points);
// for each vertex *iter, compute the centroid as avarege of the k-nearest vertices of *iter
Plane *plane = &tangent_planes[ std::distance(begin, iter) ];
@ -200,23 +200,24 @@ namespace vcg
// Step 2: build the Riemannian graph, i.e. the graph where each point is connected to the k-nearest neigbours.
dataset_bb.SetNull();
std::vector< Plane >::iterator ePlane = tangent_planes.end();
for (std::vector< Plane >::iterator iPlane=tangent_planes.begin(); iPlane!=ePlane; iPlane++)
PlaneIterator ePlane = tangent_planes.end();
for (PlaneIterator iPlane=tangent_planes.begin(); iPlane!=ePlane; iPlane++)
dataset_bb.Add(iPlane->center);
max_distance = dataset_bb.Diag();
vcg::Octree< Plane, ScalarType > octree_for_plane;
octree_for_plane.Set< std::vector<Plane>::iterator >(tangent_planes.begin(), tangent_planes.end());
octree_for_plane.Set( tangent_planes.begin(), tangent_planes.end());
std::vector< Plane* > nearest_planes(distances.size());
std::vector< std::vector< RiemannianEdge > > riemannian_graph(vertex_count); //it's probably that we are wasting the last position...
progress = 0;
sprintf(message, "Building Riemannian graph...");
for (std::vector< Plane >::iterator iPlane=tangent_planes.begin(); iPlane!=ePlane; iPlane++)
for (PlaneIterator iPlane=tangent_planes.begin(); iPlane!=ePlane; iPlane++)
{
if (callback!=NULL && (++progress%step)==0 && (percentage=int((progress*100)/vertex_count))<100) (callback)(percentage, message);
octree_for_plane.GetKClosest< PlanePointDistanceFunctor, DummyObjectMarker, std::vector< Plane* >, std::vector< ScalarType >, std::vector< CoordType > >
(PlanePointDistanceFunctor(), DummyObjectMarker(), k, iPlane->center, max_distance, nearest_planes, distances, nearest_points, true, false);
unsigned int kk = k;
octree_for_plane.GetKClosest
(PlanePointDistanceFunctor(), DummyObjectMarker(), kk, iPlane->center, max_distance, nearest_planes, distances, nearest_points, true, false);
for (int n=0; n<k; n++)
if (iPlane->index<nearest_planes[n]->index)
@ -225,8 +226,8 @@ namespace vcg
// Step 3: compute the minimum spanning tree (MST) over the Riemannian graph (we use the Kruskal algorithm)
std::vector< MSTEdge > E;
std::vector< std::vector< RiemannianEdge > >::iterator iRiemannian = riemannian_graph.begin();
std::vector< RiemannianEdge >::iterator iRiemannianEdge, eRiemannianEdge;
typename std::vector< std::vector< RiemannianEdge > >::iterator iRiemannian = riemannian_graph.begin();
typename std::vector< RiemannianEdge >::iterator iRiemannianEdge, eRiemannianEdge;
for (int i=0; i<vertex_count; i++, iRiemannian++)
for (iRiemannianEdge=iRiemannian->begin(), eRiemannianEdge=iRiemannian->end(); iRiemannianEdge!=eRiemannianEdge; iRiemannianEdge++)
E.push_back(MSTEdge(&tangent_planes[i], iRiemannianEdge->plane, iRiemannianEdge->weight));
@ -234,11 +235,11 @@ namespace vcg
std::sort( E.begin(), E.end() );
vcg::DisjointSet<Plane> set;
for (std::vector< Plane >::iterator iPlane=tangent_planes.begin(); iPlane!=ePlane; iPlane++)
for (typename std::vector< Plane >::iterator iPlane=tangent_planes.begin(); iPlane!=ePlane; iPlane++)
set.MakeSet( &*iPlane );
std::vector< MSTEdge >::iterator iMSTEdge = E.begin();
std::vector< MSTEdge >::iterator eMSTEdge = E.end();
typename std::vector< MSTEdge >::iterator iMSTEdge = E.begin();
typename std::vector< MSTEdge >::iterator eMSTEdge = E.end();
std::vector< MSTEdge > unoriented_tree;
Plane *u, *v;
for ( ; iMSTEdge!=eMSTEdge; iMSTEdge++)
@ -268,8 +269,8 @@ namespace vcg
VertexIterator iCurrentVertex, iSonVertex;
std::vector< MSTNode > MST(vertex_count);
std::vector< Plane >::iterator iFirstPlane = tangent_planes.begin();
std::vector< Plane >::iterator iCurrentPlane, iSonPlane;
typename std::vector< Plane >::iterator iFirstPlane = tangent_planes.begin();
typename std::vector< Plane >::iterator iCurrentPlane, iSonPlane;
MSTNode *mst_root;
int r_index = (root_index!=-1)? root_index : rand()*vertex_count/RAND_MAX;