Cpp autoformatter
This commit is contained in:
parent
87e032c473
commit
8a97a05969
18 changed files with 518 additions and 552 deletions
|
@ -13,14 +13,13 @@
|
||||||
#include "LineSegment.h"
|
#include "LineSegment.h"
|
||||||
#include "Point.h"
|
#include "Point.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Axis aligned bounding volume hierachy data structure.
|
* Axis aligned bounding volume hierachy data structure.
|
||||||
*/
|
*/
|
||||||
template <typename Primitive>
|
template <typename Primitive>
|
||||||
class AABBTree
|
class AABBTree
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::vector<Primitive> primitive_list;
|
typedef std::vector<Primitive> primitive_list;
|
||||||
//iterator type pointing inside the primitive list
|
//iterator type pointing inside the primitive list
|
||||||
typedef typename primitive_list::iterator PrimitiveIterator;
|
typedef typename primitive_list::iterator PrimitiveIterator;
|
||||||
|
@ -30,14 +29,17 @@ public:
|
||||||
//abstract base class defining the common interface of all aabb tree node
|
//abstract base class defining the common interface of all aabb tree node
|
||||||
class AABBNode
|
class AABBNode
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
//storage of bounding box assosiated with aabb_node
|
//storage of bounding box assosiated with aabb_node
|
||||||
Box bounds;
|
Box bounds;
|
||||||
public:
|
|
||||||
AABBNode() {
|
public:
|
||||||
|
AABBNode()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
AABBNode(const Box& b): bounds(b) {
|
AABBNode(const Box &b) : bounds(b)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the bounding box of the node
|
//returns the bounding box of the node
|
||||||
|
@ -48,27 +50,23 @@ public:
|
||||||
|
|
||||||
virtual int NumPrimitives() const = 0;
|
virtual int NumPrimitives() const = 0;
|
||||||
|
|
||||||
|
|
||||||
//this method must be implemented to return true for a leaf node and false for a non_lef node
|
//this method must be implemented to return true for a leaf node and false for a non_lef node
|
||||||
virtual bool IsLeaf() const = 0;
|
virtual bool IsLeaf() const = 0;
|
||||||
//virtual destructor
|
//virtual destructor
|
||||||
virtual ~AABBNode() {}
|
virtual ~AABBNode() {}
|
||||||
|
|
||||||
};
|
};
|
||||||
///a class representing a leaf node of an aabb tree (non split node)
|
///a class representing a leaf node of an aabb tree (non split node)
|
||||||
class AABBLeafNode: public AABBNode
|
class AABBLeafNode : public AABBNode
|
||||||
{
|
{
|
||||||
|
|
||||||
//internal storage to the range (begin and end pointer) of the primitives associated with the current leaf node
|
//internal storage to the range (begin and end pointer) of the primitives associated with the current leaf node
|
||||||
PrimitiveIterator primitivesBegin, primitivesEnd;
|
PrimitiveIterator primitivesBegin, primitivesEnd;
|
||||||
public:
|
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
//construct a leaf node from
|
//construct a leaf node from
|
||||||
AABBLeafNode(const PrimitiveIterator& primitivesBegin,
|
AABBLeafNode(const PrimitiveIterator &primitivesBegin,
|
||||||
const PrimitiveIterator& primitivesEnd,
|
const PrimitiveIterator &primitivesEnd,
|
||||||
const Box& b):
|
const Box &b) : primitivesBegin(primitivesBegin), primitivesEnd(primitivesEnd), AABBNode(b)
|
||||||
primitivesBegin(primitivesBegin),primitivesEnd(primitivesEnd), AABBNode(b)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +78,7 @@ public:
|
||||||
//returns the number primitives assosiated with the current leaf
|
//returns the number primitives assosiated with the current leaf
|
||||||
int NumPrimitives() const
|
int NumPrimitives() const
|
||||||
{
|
{
|
||||||
return (int)(primitivesEnd-primitivesBegin);
|
return (int)(primitivesEnd - primitivesBegin);
|
||||||
}
|
}
|
||||||
|
|
||||||
const_primitive_iterator begin() const
|
const_primitive_iterator begin() const
|
||||||
|
@ -92,23 +90,22 @@ public:
|
||||||
{
|
{
|
||||||
return primitivesEnd;
|
return primitivesEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
///a class representing a split node of an aabb tree (non leaf node)
|
///a class representing a split node of an aabb tree (non leaf node)
|
||||||
class AABBSplitNode: public AABBNode
|
class AABBSplitNode : public AABBNode
|
||||||
{
|
{
|
||||||
//child pointers
|
//child pointers
|
||||||
AABBNode* children[2];
|
AABBNode *children[2];
|
||||||
public:
|
|
||||||
|
public:
|
||||||
//default constructor
|
//default constructor
|
||||||
AABBSplitNode()
|
AABBSplitNode()
|
||||||
{
|
{
|
||||||
children[0] = children[1] = nullptr;
|
children[0] = children[1] = nullptr;
|
||||||
}
|
}
|
||||||
//construct a split node from given Left and right child pointers and given bounding box b of the node
|
//construct a split node from given Left and right child pointers and given bounding box b of the node
|
||||||
AABBSplitNode(AABBNode* left_child, AABBNode* right_child,const Box& b): AABBNode(b)
|
AABBSplitNode(AABBNode *left_child, AABBNode *right_child, const Box &b) : AABBNode(b)
|
||||||
{
|
{
|
||||||
children[0] = left_child;
|
children[0] = left_child;
|
||||||
children[1] = right_child;
|
children[1] = right_child;
|
||||||
|
@ -117,9 +114,9 @@ public:
|
||||||
//destructor of node, recursively deleted whole subtree
|
//destructor of node, recursively deleted whole subtree
|
||||||
~AABBSplitNode()
|
~AABBSplitNode()
|
||||||
{
|
{
|
||||||
if(Left() != nullptr)
|
if (Left() != nullptr)
|
||||||
delete Left();
|
delete Left();
|
||||||
if(Right() != nullptr)
|
if (Right() != nullptr)
|
||||||
delete Right();
|
delete Right();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,24 +127,24 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns a pointer to the left child node
|
//returns a pointer to the left child node
|
||||||
AABBNode* Left()
|
AABBNode *Left()
|
||||||
{
|
{
|
||||||
return children[0];
|
return children[0];
|
||||||
}
|
}
|
||||||
//returns a pointer to the right child node
|
//returns a pointer to the right child node
|
||||||
AABBNode* Right()
|
AABBNode *Right()
|
||||||
{
|
{
|
||||||
return children[1];
|
return children[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns a const pointer to the left child node
|
//returns a const pointer to the left child node
|
||||||
const AABBNode* Left() const
|
const AABBNode *Left() const
|
||||||
{
|
{
|
||||||
return children[0];
|
return children[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns a const pointer to the right child node
|
//returns a const pointer to the right child node
|
||||||
const AABBNode* Right() const
|
const AABBNode *Right() const
|
||||||
{
|
{
|
||||||
return children[1];
|
return children[1];
|
||||||
}
|
}
|
||||||
|
@ -157,25 +154,25 @@ public:
|
||||||
{
|
{
|
||||||
return Left()->NumPrimitives() + Right()->NumPrimitives();
|
return Left()->NumPrimitives() + Right()->NumPrimitives();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//search entry used internally for nearest and k nearest primitive queries
|
//search entry used internally for nearest and k nearest primitive queries
|
||||||
struct SearchEntry
|
struct SearchEntry
|
||||||
{
|
{
|
||||||
//squared distance to node from query point
|
//squared distance to node from query point
|
||||||
float sqrDistance;
|
float sqrDistance;
|
||||||
//node
|
//node
|
||||||
const AABBNode* node;
|
const AABBNode *node;
|
||||||
|
|
||||||
//constructor
|
//constructor
|
||||||
SearchEntry(float sqrDistance, const AABBNode* node)
|
SearchEntry(float sqrDistance, const AABBNode *node)
|
||||||
: sqrDistance(sqrDistance), node(node)
|
: sqrDistance(sqrDistance), node(node)
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
|
|
||||||
//search entry a < b means a.sqr_distance > b. sqr_distance
|
//search entry a < b means a.sqr_distance > b. sqr_distance
|
||||||
bool operator<(const SearchEntry& e) const
|
bool operator<(const SearchEntry &e) const
|
||||||
{
|
{
|
||||||
return sqrDistance > e.sqrDistance;
|
return sqrDistance > e.sqrDistance;
|
||||||
}
|
}
|
||||||
|
@ -187,17 +184,19 @@ private:
|
||||||
//squared distance from query point to primitive
|
//squared distance from query point to primitive
|
||||||
float sqrDistance;
|
float sqrDistance;
|
||||||
//pointer to primitive
|
//pointer to primitive
|
||||||
const Primitive* prim;
|
const Primitive *prim;
|
||||||
//default constructor
|
//default constructor
|
||||||
ResultEntry()
|
ResultEntry()
|
||||||
: sqrDistance(std::numeric_limits<float>::infinity()), prim(nullptr)
|
: sqrDistance(std::numeric_limits<float>::infinity()), prim(nullptr)
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
//constructor
|
//constructor
|
||||||
ResultEntry(float sqrDistance, const Primitive* p)
|
ResultEntry(float sqrDistance, const Primitive *p)
|
||||||
: sqrDistance(sqrDistance), prim(p)
|
: sqrDistance(sqrDistance), prim(p)
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
//result_entry are sorted by their sqr_distance using this less than operator
|
//result_entry are sorted by their sqr_distance using this less than operator
|
||||||
bool operator<(const ResultEntry& e) const
|
bool operator<(const ResultEntry &e) const
|
||||||
{
|
{
|
||||||
return sqrDistance < e.sqrDistance;
|
return sqrDistance < e.sqrDistance;
|
||||||
}
|
}
|
||||||
|
@ -214,17 +213,16 @@ private:
|
||||||
//a flag indicating if the tree is constructed
|
//a flag indicating if the tree is constructed
|
||||||
bool completed;
|
bool completed;
|
||||||
|
|
||||||
|
public:
|
||||||
public:
|
|
||||||
//returns a pointer to the root node of the tree
|
//returns a pointer to the root node of the tree
|
||||||
AABBNode* Root()
|
AABBNode *Root()
|
||||||
{
|
{
|
||||||
assert(IsCompleted());
|
assert(IsCompleted());
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns a const pointer to the root node of the tree
|
//returns a const pointer to the root node of the tree
|
||||||
const AABBNode* Root() const
|
const AABBNode *Root() const
|
||||||
{
|
{
|
||||||
assert(IsCompleted());
|
assert(IsCompleted());
|
||||||
return root;
|
return root;
|
||||||
|
@ -233,53 +231,51 @@ public:
|
||||||
//constructor of aabb tree
|
//constructor of aabb tree
|
||||||
//default maximal tree depth is 20
|
//default maximal tree depth is 20
|
||||||
//default minimal size of a node not to be further subdivided in the cnstruction process is two
|
//default minimal size of a node not to be further subdivided in the cnstruction process is two
|
||||||
AABBTree(int maxDepth=20, int minSize=2):
|
AABBTree(int maxDepth = 20, int minSize = 2) : maxDepth(maxDepth), minSize(minSize), root(nullptr), completed(false)
|
||||||
maxDepth(maxDepth),minSize(minSize),root(nullptr),completed(false)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//copy constructor
|
//copy constructor
|
||||||
AABBTree(const AABBTree& other)
|
AABBTree(const AABBTree &other)
|
||||||
{
|
{
|
||||||
primitives = other.primitives;
|
primitives = other.primitives;
|
||||||
maxDepth = other.maxDepth;
|
maxDepth = other.maxDepth;
|
||||||
minSize = other.minSize;
|
minSize = other.minSize;
|
||||||
root = CopyTree(other.primitives,other.root);
|
root = CopyTree(other.primitives, other.root);
|
||||||
completed = other.completed;
|
completed = other.completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
//move constructor
|
//move constructor
|
||||||
AABBTree(AABBTree&& other):root(nullptr),completed(false)
|
AABBTree(AABBTree &&other) : root(nullptr), completed(false)
|
||||||
{
|
{
|
||||||
*this = std::move(other);
|
*this = std::move(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
//copy assignment operator
|
//copy assignment operator
|
||||||
AABBTree& operator=(const AABBTree& other)
|
AABBTree &operator=(const AABBTree &other)
|
||||||
{
|
{
|
||||||
if(this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
if(root != nullptr)
|
if (root != nullptr)
|
||||||
delete root;
|
delete root;
|
||||||
primitives = other.primitives;
|
primitives = other.primitives;
|
||||||
maxDepth = other.maxDepth;
|
maxDepth = other.maxDepth;
|
||||||
minSize = other.minSize;
|
minSize = other.minSize;
|
||||||
root = CopyTree(other.primitives,other.root);
|
root = CopyTree(other.primitives, other.root);
|
||||||
completed = other.completed;
|
completed = other.completed;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//move assign operator
|
//move assign operator
|
||||||
AABBTree& operator=(AABBTree&& other)
|
AABBTree &operator=(AABBTree &&other)
|
||||||
{
|
{
|
||||||
if(this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
std::swap(primitives,other.primitives);
|
std::swap(primitives, other.primitives);
|
||||||
std::swap(maxDepth, other.maxDepth);
|
std::swap(maxDepth, other.maxDepth);
|
||||||
std::swap(minSize, other.minSize);
|
std::swap(minSize, other.minSize);
|
||||||
std::swap(root,other.root) ;
|
std::swap(root, other.root);
|
||||||
std::swap(completed, other.completed);
|
std::swap(completed, other.completed);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -289,7 +285,7 @@ public:
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
primitives.clear();
|
primitives.clear();
|
||||||
if(root != nullptr)
|
if (root != nullptr)
|
||||||
{
|
{
|
||||||
delete root;
|
delete root;
|
||||||
root = nullptr;
|
root = nullptr;
|
||||||
|
@ -306,24 +302,24 @@ public:
|
||||||
//insert a primitive into internal primitive list
|
//insert a primitive into internal primitive list
|
||||||
//this method do not construct the tree!
|
//this method do not construct the tree!
|
||||||
//call the method Complete, after insertion of all primitives
|
//call the method Complete, after insertion of all primitives
|
||||||
void Insert(const Primitive& p)
|
void Insert(const Primitive &p)
|
||||||
{
|
{
|
||||||
primitives.push_back(p);
|
primitives.push_back(p);
|
||||||
completed=false;
|
completed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//construct the tree from all prior inserted primitives
|
//construct the tree from all prior inserted primitives
|
||||||
void Complete()
|
void Complete()
|
||||||
{
|
{
|
||||||
//if tree already constructed -> delete tree
|
//if tree already constructed -> delete tree
|
||||||
if(root != nullptr)
|
if (root != nullptr)
|
||||||
delete root;
|
delete root;
|
||||||
//compute bounding box over all primitives using helper function
|
//compute bounding box over all primitives using helper function
|
||||||
Box bounds = ComputeBounds(primitives.begin(),primitives.end());
|
Box bounds = ComputeBounds(primitives.begin(), primitives.end());
|
||||||
//initial call to the recursive tree construction method over the whole range of primitives
|
//initial call to the recursive tree construction method over the whole range of primitives
|
||||||
root = Build(primitives.begin(),primitives.end(),bounds,0);
|
root = Build(primitives.begin(), primitives.end(), bounds, 0);
|
||||||
//set completed flag to true
|
//set completed flag to true
|
||||||
completed=true;
|
completed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns true if the tree can be used for queries
|
//returns true if the tree can be used for queries
|
||||||
|
@ -334,15 +330,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//closest primitive computation via linear search
|
//closest primitive computation via linear search
|
||||||
ResultEntry ClosestPrimitiveLinearSearch(const Eigen::Vector3f& q) const
|
ResultEntry ClosestPrimitiveLinearSearch(const Eigen::Vector3f &q) const
|
||||||
{
|
{
|
||||||
ResultEntry best;
|
ResultEntry best;
|
||||||
|
|
||||||
auto pend = primitives.end();
|
auto pend = primitives.end();
|
||||||
for(auto pit = primitives.begin(); pit != pend; ++pit)
|
for (auto pit = primitives.begin(); pit != pend; ++pit)
|
||||||
{
|
{
|
||||||
float dist = pit->SqrDistance(q);
|
float dist = pit->SqrDistance(q);
|
||||||
if(dist < best.sqrDistance)
|
if (dist < best.sqrDistance)
|
||||||
{
|
{
|
||||||
best.sqrDistance = dist;
|
best.sqrDistance = dist;
|
||||||
best.prim = &(*pit);
|
best.prim = &(*pit);
|
||||||
|
@ -352,109 +348,104 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//computes the k nearest neighbor primitives via linear search
|
//computes the k nearest neighbor primitives via linear search
|
||||||
std::vector<ResultEntry> ClosestKPrimitivesLinearSearch(size_t k, const Eigen::Vector3f& q) const
|
std::vector<ResultEntry> ClosestKPrimitivesLinearSearch(size_t k, const Eigen::Vector3f &q) const
|
||||||
{
|
{
|
||||||
std::priority_queue<ResultEntry> k_best;
|
std::priority_queue<ResultEntry> k_best;
|
||||||
|
|
||||||
Primitive best_p;
|
Primitive best_p;
|
||||||
auto pend = primitives.end();
|
auto pend = primitives.end();
|
||||||
for(auto pit = primitives.begin(); pit != pend; ++pit)
|
for (auto pit = primitives.begin(); pit != pend; ++pit)
|
||||||
{
|
{
|
||||||
float dist = pit->SqrDistance(q);
|
float dist = pit->SqrDistance(q);
|
||||||
if(k_best.size() < k )
|
if (k_best.size() < k)
|
||||||
{
|
{
|
||||||
k_best.push(ResultEntry(dist,*pit));
|
k_best.push(ResultEntry(dist, *pit));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(k_best.top().SqrDistance > dist)
|
if (k_best.top().SqrDistance > dist)
|
||||||
{
|
{
|
||||||
k_best.pop();
|
k_best.pop();
|
||||||
k_best.push(ResultEntry(dist,*pit));
|
k_best.push(ResultEntry(dist, *pit));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::vector<ResultEntry> result(k_best.size());
|
std::vector<ResultEntry> result(k_best.size());
|
||||||
auto rend = result.end();
|
auto rend = result.end();
|
||||||
for(auto rit = result.begin(); rit != rend; ++rit)
|
for (auto rit = result.begin(); rit != rend; ++rit)
|
||||||
{
|
{
|
||||||
*rit = k_best.top();
|
*rit = k_best.top();
|
||||||
k_best.pop();
|
k_best.pop();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//closest k primitive computation
|
//closest k primitive computation
|
||||||
std::vector<ResultEntry> ClosestKPrimitives(size_t k,const Eigen::Vector3f& q) const
|
std::vector<ResultEntry> ClosestKPrimitives(size_t k, const Eigen::Vector3f &q) const
|
||||||
{
|
{
|
||||||
//student begin
|
//student begin
|
||||||
return ClosestKPrimitivesLinearSearch(k,q);
|
return ClosestKPrimitivesLinearSearch(k, q);
|
||||||
//student end
|
//student end
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the closest primitive and its squared distance to the point q
|
//returns the closest primitive and its squared distance to the point q
|
||||||
ResultEntry ClosestPrimitive(const Eigen::Vector3f& q) const
|
ResultEntry ClosestPrimitive(const Eigen::Vector3f &q) const
|
||||||
{
|
{
|
||||||
assert(IsCompleted());
|
assert(IsCompleted());
|
||||||
if(root == nullptr)
|
if (root == nullptr)
|
||||||
return ResultEntry();
|
return ResultEntry();
|
||||||
/* Task 3.2.1 */
|
/* Task 3.2.1 */
|
||||||
return ClosestPrimitiveLinearSearch(q);
|
return ClosestPrimitiveLinearSearch(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
//return the closest point position on the closest primitive in the tree with respect to the query point q
|
//return the closest point position on the closest primitive in the tree with respect to the query point q
|
||||||
Eigen::Vector3f ClosestPoint(const Eigen::Vector3f& p) const
|
Eigen::Vector3f ClosestPoint(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
ResultEntry r = ClosestPrimitive(p);
|
ResultEntry r = ClosestPrimitive(p);
|
||||||
return r.prim->ClosestPoint(p);
|
return r.prim->ClosestPoint(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
//return the squared distance between point p and the nearest primitive in the tree
|
//return the squared distance between point p and the nearest primitive in the tree
|
||||||
float SqrDistance(const Eigen::Vector3f& p) const
|
float SqrDistance(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
ResultEntry r = ClosestPrimitive(p);
|
ResultEntry r = ClosestPrimitive(p);
|
||||||
return r.SqrDistance;
|
return r.SqrDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
//return the euclidean distance between point p and the nearest primitive in the tree
|
//return the euclidean distance between point p and the nearest primitive in the tree
|
||||||
float Distance(const Eigen::Vector3f& p) const
|
float Distance(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
return sqrt(SqrDistance(p));
|
return sqrt(SqrDistance(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
protected:
|
|
||||||
|
|
||||||
//helper function to copy a subtree
|
//helper function to copy a subtree
|
||||||
AABBNode* CopyTree(const primitive_list& other_primitives,AABBNode* node)
|
AABBNode *CopyTree(const primitive_list &other_primitives, AABBNode *node)
|
||||||
{
|
{
|
||||||
if(node == nullptr)
|
if (node == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if(node->IsLeaf())
|
if (node->IsLeaf())
|
||||||
{
|
{
|
||||||
AABBLeafNode* leaf = (AABBLeafNode*)node;
|
AABBLeafNode *leaf = (AABBLeafNode *)node;
|
||||||
return new AABBLeafNode(primitives.begin()+(leaf->primitives.begin()-other_primitives.begin()),
|
return new AABBLeafNode(primitives.begin() + (leaf->primitives.begin() - other_primitives.begin()),
|
||||||
primitives.begin()+(leaf->primitives.end()-other_primitives.begin()));
|
primitives.begin() + (leaf->primitives.end() - other_primitives.begin()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AABBSplitNode* split = (AABBSplitNode*)node;
|
AABBSplitNode *split = (AABBSplitNode *)node;
|
||||||
return new AABBSplitNode(CopyTree(other_primitives,split->Left()),
|
return new AABBSplitNode(CopyTree(other_primitives, split->Left()),
|
||||||
CopyTree(other_primitives,split->Right()));
|
CopyTree(other_primitives, split->Right()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//helper function to compute an axis aligned bounding box over the range of primitives [begin,end)
|
//helper function to compute an axis aligned bounding box over the range of primitives [begin,end)
|
||||||
Box ComputeBounds(const_primitive_iterator begin,
|
Box ComputeBounds(const_primitive_iterator begin,
|
||||||
const_primitive_iterator end)
|
const_primitive_iterator end)
|
||||||
{
|
{
|
||||||
Box bounds;
|
Box bounds;
|
||||||
for(auto pit = begin; pit != end; ++pit)
|
for (auto pit = begin; pit != end; ++pit)
|
||||||
bounds.Insert(pit->ComputeBounds());
|
bounds.Insert(pit->ComputeBounds());
|
||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//recursive tree construction initially called from method complete()
|
//recursive tree construction initially called from method complete()
|
||||||
//build an aabb (sub)-tree over the range of primitives [begin,end),
|
//build an aabb (sub)-tree over the range of primitives [begin,end),
|
||||||
//the current bounding box is given by bounds and the current tree depth is given by the parameter depth
|
//the current bounding box is given by bounds and the current tree depth is given by the parameter depth
|
||||||
|
@ -468,46 +459,42 @@ protected:
|
||||||
// the STL routine std::nth_element would be very useful here , you only have to provide a ordering predicate
|
// the STL routine std::nth_element would be very useful here , you only have to provide a ordering predicate
|
||||||
//compute the boundg boxed of the two resulting sub ranges and recursivly call build on the two subranges
|
//compute the boundg boxed of the two resulting sub ranges and recursivly call build on the two subranges
|
||||||
//the resulting subtree are used as children of the resulting split node.
|
//the resulting subtree are used as children of the resulting split node.
|
||||||
AABBNode* Build(PrimitiveIterator begin, PrimitiveIterator end, Box& bounds, int depth)
|
AABBNode *Build(PrimitiveIterator begin, PrimitiveIterator end, Box &bounds, int depth)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(depth >= maxDepth || end-begin <= minSize)
|
if (depth >= maxDepth || end - begin <= minSize)
|
||||||
{
|
{
|
||||||
return new AABBLeafNode(begin,end,bounds);
|
return new AABBLeafNode(begin, end, bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
Eigen::Vector3f e = bounds.Extents();
|
Eigen::Vector3f e = bounds.Extents();
|
||||||
|
|
||||||
int axis = 0;
|
int axis = 0;
|
||||||
float max_extent = e[0];
|
float max_extent = e[0];
|
||||||
if(max_extent < e[1])
|
if (max_extent < e[1])
|
||||||
{
|
{
|
||||||
axis = 1;
|
axis = 1;
|
||||||
max_extent = e[1];
|
max_extent = e[1];
|
||||||
}
|
}
|
||||||
if(max_extent < e[2])
|
if (max_extent < e[2])
|
||||||
{
|
{
|
||||||
axis = 2;
|
axis = 2;
|
||||||
max_extent = e[2];
|
max_extent = e[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrimitiveIterator mid = begin + (end - begin) / 2;
|
||||||
|
std::nth_element(begin, mid, end, [&axis](const Primitive &a, const Primitive &b) { return a.ReferencePoint()[axis] < b.ReferencePoint()[axis]; });
|
||||||
|
|
||||||
PrimitiveIterator mid= begin + (end-begin)/2;
|
Box lbounds = ComputeBounds(begin, mid);
|
||||||
std::nth_element(begin,mid,end,[&axis](const Primitive& a, const Primitive& b)
|
Box rbounds = ComputeBounds(mid, end);
|
||||||
{ return a.ReferencePoint()[axis] < b.ReferencePoint()[axis];});
|
|
||||||
|
|
||||||
Box lbounds = ComputeBounds(begin,mid);
|
|
||||||
Box rbounds = ComputeBounds(mid,end);
|
|
||||||
|
|
||||||
return new AABBSplitNode(Build(begin,mid,lbounds,depth+1),Build(mid,end,rbounds,depth+1),bounds);
|
|
||||||
|
|
||||||
|
return new AABBSplitNode(Build(begin, mid, lbounds, depth + 1), Build(mid, end, rbounds, depth + 1), bounds);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//helper function to construct an aabb tree data structure from the triangle faces of the halfedge mesh m
|
//helper function to construct an aabb tree data structure from the triangle faces of the halfedge mesh m
|
||||||
void BuildAABBTreeFromTriangles(const HEMesh& m, AABBTree<Triangle >& tree);
|
void BuildAABBTreeFromTriangles(const HEMesh &m, AABBTree<Triangle> &tree);
|
||||||
//helper function to construct an aabb tree data structure from the vertices of the halfedge mesh m
|
//helper function to construct an aabb tree data structure from the vertices of the halfedge mesh m
|
||||||
void BuildAABBTreeFromVertices(const HEMesh& m, AABBTree<Point>& tree);
|
void BuildAABBTreeFromVertices(const HEMesh &m, AABBTree<Point> &tree);
|
||||||
//helper function to construct an aabb tree data structure from the edges of the halfedge mesh m
|
//helper function to construct an aabb tree data structure from the edges of the halfedge mesh m
|
||||||
void BuildAABBTreeFromEdges(const HEMesh& m, AABBTree<LineSegment>& tree);
|
void BuildAABBTreeFromEdges(const HEMesh &m, AABBTree<LineSegment> &tree);
|
||||||
|
|
||||||
|
|
|
@ -11,25 +11,24 @@ class Box
|
||||||
//internal storage for lower and upper corner points of the box
|
//internal storage for lower and upper corner points of the box
|
||||||
std::pair<Eigen::Vector3f, Eigen::Vector3f> bounds;
|
std::pair<Eigen::Vector3f, Eigen::Vector3f> bounds;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//creates an empty box like the method Clear
|
//creates an empty box like the method Clear
|
||||||
Box();
|
Box();
|
||||||
|
|
||||||
//construct a box with the gven lower and upper corner points
|
//construct a box with the gven lower and upper corner points
|
||||||
Box(const Eigen::Vector3f& lbound, const Eigen::Vector3f& ubound);
|
Box(const Eigen::Vector3f &lbound, const Eigen::Vector3f &ubound);
|
||||||
|
|
||||||
//returns the corner point which is the lower bound of the box in all dimensions
|
//returns the corner point which is the lower bound of the box in all dimensions
|
||||||
Eigen::Vector3f& LowerBound();
|
Eigen::Vector3f &LowerBound();
|
||||||
|
|
||||||
//returns the corner point which is the lower bound of the box in all dimensions
|
//returns the corner point which is the lower bound of the box in all dimensions
|
||||||
const Eigen::Vector3f& LowerBound() const;
|
const Eigen::Vector3f &LowerBound() const;
|
||||||
|
|
||||||
//returns the corner point which is the upper bound of the box in all dimensions
|
//returns the corner point which is the upper bound of the box in all dimensions
|
||||||
Eigen::Vector3f& UpperBound();
|
Eigen::Vector3f &UpperBound();
|
||||||
|
|
||||||
//returns the corner point which is the upper bound of the box in all dimensions
|
//returns the corner point which is the upper bound of the box in all dimensions
|
||||||
const Eigen::Vector3f& UpperBound() const;
|
const Eigen::Vector3f &UpperBound() const;
|
||||||
|
|
||||||
//returns a vector containing the extents of the box in all dimensions
|
//returns a vector containing the extents of the box in all dimensions
|
||||||
Eigen::Vector3f Extents() const;
|
Eigen::Vector3f Extents() const;
|
||||||
|
@ -49,33 +48,32 @@ public:
|
||||||
//returns the box radius for a given direction vector a
|
//returns the box radius for a given direction vector a
|
||||||
//if the box is centered at the origin
|
//if the box is centered at the origin
|
||||||
//then the projection of the box on direction a is contained within the Interval [-r,r]
|
//then the projection of the box on direction a is contained within the Interval [-r,r]
|
||||||
float Radius(const Eigen::Vector3f& a) const;
|
float Radius(const Eigen::Vector3f &a) const;
|
||||||
|
|
||||||
//returns true if the box b overlaps with the current one
|
//returns true if the box b overlaps with the current one
|
||||||
bool Overlaps(const Box& b) const;
|
bool Overlaps(const Box &b) const;
|
||||||
|
|
||||||
//returns true if the point p is inside this box
|
//returns true if the point p is inside this box
|
||||||
bool IsInside(const Eigen::Vector3f& p) const;
|
bool IsInside(const Eigen::Vector3f &p) const;
|
||||||
|
|
||||||
//returns true if box b is inside this box
|
//returns true if box b is inside this box
|
||||||
bool IsInside(const Box& b) const;
|
bool IsInside(const Box &b) const;
|
||||||
|
|
||||||
//creates a box which goes from [+infinity,- infinity] in al dimensions
|
//creates a box which goes from [+infinity,- infinity] in al dimensions
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
//enlarges the box such that the point p is inside afterwards
|
//enlarges the box such that the point p is inside afterwards
|
||||||
void Insert(const Eigen::Vector3f& p);
|
void Insert(const Eigen::Vector3f &p);
|
||||||
|
|
||||||
//enlarges the box such that box b is inside afterwards
|
//enlarges the box such that box b is inside afterwards
|
||||||
void Insert(const Box& b);
|
void Insert(const Box &b);
|
||||||
|
|
||||||
//returns the point on or inside the box with the smallest distance to p
|
//returns the point on or inside the box with the smallest distance to p
|
||||||
Eigen::Vector3f ClosestPoint(const Eigen::Vector3f& p) const;
|
Eigen::Vector3f ClosestPoint(const Eigen::Vector3f &p) const;
|
||||||
|
|
||||||
//returns the squared distance between p and the box
|
//returns the squared distance between p and the box
|
||||||
float SqrDistance(const Eigen::Vector3f& p) const;
|
float SqrDistance(const Eigen::Vector3f &p) const;
|
||||||
|
|
||||||
//returns the euclidean distance between p and the box
|
//returns the euclidean distance between p and the box
|
||||||
float Distance(const Eigen::Vector3f& p) const;
|
float Distance(const Eigen::Vector3f &p) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
class GridTraverser
|
class GridTraverser
|
||||||
{
|
{
|
||||||
//ray origin and direction
|
//ray origin and direction
|
||||||
Eigen::Vector3f orig,dir;
|
Eigen::Vector3f orig, dir;
|
||||||
//grid cell extents
|
//grid cell extents
|
||||||
Eigen::Vector3f cellExtents;
|
Eigen::Vector3f cellExtents;
|
||||||
//current cell index
|
//current cell index
|
||||||
|
@ -18,27 +18,27 @@ class GridTraverser
|
||||||
|
|
||||||
/* you can additional attributes for incremental calculation here */
|
/* you can additional attributes for incremental calculation here */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//default constructor
|
//default constructor
|
||||||
GridTraverser();
|
GridTraverser();
|
||||||
|
|
||||||
//constructs a grid traverser for a given ray with origin o, and ray direction d for a grid with cell extents ce
|
//constructs a grid traverser for a given ray with origin o, and ray direction d for a grid with cell extents ce
|
||||||
GridTraverser(const Eigen::Vector3f& o, const Eigen::Vector3f&d, const Eigen::Vector3f ce);
|
GridTraverser(const Eigen::Vector3f &o, const Eigen::Vector3f &d, const Eigen::Vector3f ce);
|
||||||
|
|
||||||
//accessor of ray origin
|
//accessor of ray origin
|
||||||
Eigen::Vector3f& Origin();
|
Eigen::Vector3f &Origin();
|
||||||
|
|
||||||
//const accessor of ray origin
|
//const accessor of ray origin
|
||||||
const Eigen::Vector3f& Origin() const;
|
const Eigen::Vector3f &Origin() const;
|
||||||
|
|
||||||
//accessor of ray direction
|
//accessor of ray direction
|
||||||
Eigen::Vector3f& Direction();
|
Eigen::Vector3f &Direction();
|
||||||
|
|
||||||
//const accessor of ray direction
|
//const accessor of ray direction
|
||||||
const Eigen::Vector3f& Direction() const;
|
const Eigen::Vector3f &Direction() const;
|
||||||
|
|
||||||
//set cell extents
|
//set cell extents
|
||||||
void SetCellExtents(const Eigen::Vector3f& cellExtent);
|
void SetCellExtents(const Eigen::Vector3f &cellExtent);
|
||||||
|
|
||||||
//init at origin cell
|
//init at origin cell
|
||||||
void Init();
|
void Init();
|
||||||
|
|
|
@ -20,33 +20,31 @@ class LineSegment
|
||||||
//this edge handle can be used to optionally identify the edge in a halfedge mesh data structure instance
|
//this edge handle can be used to optionally identify the edge in a halfedge mesh data structure instance
|
||||||
OpenMesh::EdgeHandle h;
|
OpenMesh::EdgeHandle h;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//default constructor
|
//default constructor
|
||||||
LineSegment();
|
LineSegment();
|
||||||
|
|
||||||
//constructs a line segment by the two end points v0, v1 without using the edge handle
|
//constructs a line segment by the two end points v0, v1 without using the edge handle
|
||||||
LineSegment(const Eigen::Vector3f& v0, const Eigen::Vector3f& v1);
|
LineSegment(const Eigen::Vector3f &v0, const Eigen::Vector3f &v1);
|
||||||
|
|
||||||
//construct a line segment from the edge e of the halfedge mesh m
|
//construct a line segment from the edge e of the halfedge mesh m
|
||||||
LineSegment(const HEMesh& m,const OpenMesh::EdgeHandle& e);
|
LineSegment(const HEMesh &m, const OpenMesh::EdgeHandle &e);
|
||||||
|
|
||||||
//returns an axis aligned bounding box of the line segment
|
//returns an axis aligned bounding box of the line segment
|
||||||
Box ComputeBounds() const;
|
Box ComputeBounds() const;
|
||||||
|
|
||||||
//returns true if the line segment overlaps the given box b
|
//returns true if the line segment overlaps the given box b
|
||||||
bool Overlaps(const Box& b) const;
|
bool Overlaps(const Box &b) const;
|
||||||
|
|
||||||
//returns the point with smallest distance topoint p which lies on the line segment
|
//returns the point with smallest distance topoint p which lies on the line segment
|
||||||
Eigen::Vector3f ClosestPoint(const Eigen::Vector3f& p) const;
|
Eigen::Vector3f ClosestPoint(const Eigen::Vector3f &p) const;
|
||||||
|
|
||||||
//returns the squared distance between point p and the line segment
|
//returns the squared distance between point p and the line segment
|
||||||
float SqrDistance(const Eigen::Vector3f& p) const;
|
float SqrDistance(const Eigen::Vector3f &p) const;
|
||||||
|
|
||||||
//returns the euclidean distance between point p and the line segment
|
//returns the euclidean distance between point p and the line segment
|
||||||
float Distance(const Eigen::Vector3f& p) const;
|
float Distance(const Eigen::Vector3f &p) const;
|
||||||
|
|
||||||
//returns a reference point which is on the line segment and is used to sort the primitive in the AABB tree construction
|
//returns a reference point which is on the line segment and is used to sort the primitive in the AABB tree construction
|
||||||
Eigen::Vector3f ReferencePoint() const;
|
Eigen::Vector3f ReferencePoint() const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "Box.h"
|
#include "Box.h"
|
||||||
#include "util/OpenMeshUtils.h"
|
#include "util/OpenMeshUtils.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
a triangle primitive which can be used with the AABBTree and the HashGrid data structure
|
a triangle primitive which can be used with the AABBTree and the HashGrid data structure
|
||||||
*/
|
*/
|
||||||
|
@ -21,28 +20,25 @@ class Triangle
|
||||||
//internal storage of the optional face handle to identify the originating face in a half edge mesh instance
|
//internal storage of the optional face handle to identify the originating face in a half edge mesh instance
|
||||||
OpenMesh::FaceHandle h;
|
OpenMesh::FaceHandle h;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//default constructor
|
//default constructor
|
||||||
Triangle();
|
Triangle();
|
||||||
//constructs a triangle using the vertex positions v0,v1 and v2
|
//constructs a triangle using the vertex positions v0,v1 and v2
|
||||||
Triangle(const Eigen::Vector3f& v0, const Eigen::Vector3f& v1,const Eigen::Vector3f& v2);
|
Triangle(const Eigen::Vector3f &v0, const Eigen::Vector3f &v1, const Eigen::Vector3f &v2);
|
||||||
//constructs a triangle from the face f of the given halfedge mesh m
|
//constructs a triangle from the face f of the given halfedge mesh m
|
||||||
Triangle(const HEMesh&m, const OpenMesh::FaceHandle& f);
|
Triangle(const HEMesh &m, const OpenMesh::FaceHandle &f);
|
||||||
//returns the axis aligned bounding box of the triangle
|
//returns the axis aligned bounding box of the triangle
|
||||||
Box ComputeBounds() const;
|
Box ComputeBounds() const;
|
||||||
//returns true if the triangle overlaps the given box b
|
//returns true if the triangle overlaps the given box b
|
||||||
bool Overlaps(const Box& b) const;
|
bool Overlaps(const Box &b) const;
|
||||||
//returns the barycentric coordinates of the point with thesmallest distance to point p which lies on the triangle
|
//returns the barycentric coordinates of the point with thesmallest distance to point p which lies on the triangle
|
||||||
void ClosestPointBarycentric(const Eigen::Vector3f& p, float& l0, float& l1, float& l2) const;
|
void ClosestPointBarycentric(const Eigen::Vector3f &p, float &l0, float &l1, float &l2) const;
|
||||||
//returns the point with smallest distance to point p which lies on the triangle
|
//returns the point with smallest distance to point p which lies on the triangle
|
||||||
Eigen::Vector3f ClosestPoint(const Eigen::Vector3f& p) const;
|
Eigen::Vector3f ClosestPoint(const Eigen::Vector3f &p) const;
|
||||||
//returns the squared distance between point p and the triangle
|
//returns the squared distance between point p and the triangle
|
||||||
float SqrDistance(const Eigen::Vector3f& p) const;
|
float SqrDistance(const Eigen::Vector3f &p) const;
|
||||||
//returns the euclidean distance between point p and the triangle
|
//returns the euclidean distance between point p and the triangle
|
||||||
float Distance(const Eigen::Vector3f& p) const;
|
float Distance(const Eigen::Vector3f &p) const;
|
||||||
//returns a reference point which is on the triangle and is used to sort the primitive in the AABB tree construction
|
//returns a reference point which is on the triangle and is used to sort the primitive in the AABB tree construction
|
||||||
Eigen::Vector3f ReferencePoint() const;
|
Eigen::Vector3f ReferencePoint() const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,27 +18,28 @@
|
||||||
|
|
||||||
class Viewer : public nse::gui::AbstractViewer
|
class Viewer : public nse::gui::AbstractViewer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Viewer();
|
Viewer();
|
||||||
|
|
||||||
void drawContents();
|
void drawContents();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum PrimitiveType
|
enum PrimitiveType
|
||||||
{
|
{
|
||||||
Vertex, Edge, Tri
|
Vertex,
|
||||||
|
Edge,
|
||||||
|
Tri
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetupGUI();
|
void SetupGUI();
|
||||||
void MeshUpdated();
|
void MeshUpdated();
|
||||||
|
|
||||||
void FindClosestPoint(const Eigen::Vector3f& p);
|
void FindClosestPoint(const Eigen::Vector3f &p);
|
||||||
void BuildGridVBO();
|
void BuildGridVBO();
|
||||||
void BuildRayVBOs();
|
void BuildRayVBOs();
|
||||||
|
|
||||||
template <typename Grid>
|
template <typename Grid>
|
||||||
void BuildGridVBO(const Grid& grid)
|
void BuildGridVBO(const Grid &grid)
|
||||||
{
|
{
|
||||||
std::vector<Eigen::Vector4f> positions;
|
std::vector<Eigen::Vector4f> positions;
|
||||||
for (auto it = grid.NonEmptyCellsBegin(); it != grid.NonEmptyCellsEnd(); ++it)
|
for (auto it = grid.NonEmptyCellsBegin(); it != grid.NonEmptyCellsEnd(); ++it)
|
||||||
|
@ -54,16 +55,16 @@ private:
|
||||||
gridIndices = (GLuint)positions.size();
|
gridIndices = (GLuint)positions.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddBoxVertices(const Box& box, std::vector<Eigen::Vector4f>& positions);
|
void AddBoxVertices(const Box &box, std::vector<Eigen::Vector4f> &positions);
|
||||||
|
|
||||||
nanogui::ComboBox* shadingBtn;
|
nanogui::ComboBox *shadingBtn;
|
||||||
nanogui::CheckBox* chkRenderMesh;
|
nanogui::CheckBox *chkRenderMesh;
|
||||||
nanogui::CheckBox* chkRenderGrid;
|
nanogui::CheckBox *chkRenderGrid;
|
||||||
nanogui::CheckBox* chkRenderRay;
|
nanogui::CheckBox *chkRenderRay;
|
||||||
int raySteps;
|
int raySteps;
|
||||||
|
|
||||||
nse::gui::VectorInput* sldQuery, *sldRayOrigin, *sldRayDir;
|
nse::gui::VectorInput *sldQuery, *sldRayOrigin, *sldRayDir;
|
||||||
nanogui::ComboBox* cmbPrimitiveType;
|
nanogui::ComboBox *cmbPrimitiveType;
|
||||||
|
|
||||||
HEMesh polymesh;
|
HEMesh polymesh;
|
||||||
float bboxMaxLength;
|
float bboxMaxLength;
|
||||||
|
|
|
@ -5,37 +5,37 @@
|
||||||
#include "AABBTree.h"
|
#include "AABBTree.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
void BuildAABBTreeFromTriangles(const HEMesh& m, AABBTree<Triangle >& tree)
|
void BuildAABBTreeFromTriangles(const HEMesh &m, AABBTree<Triangle> &tree)
|
||||||
{
|
{
|
||||||
std::cout << "Building AABB tree from triangles .." << std::endl;
|
std::cout << "Building AABB tree from triangles .." << std::endl;
|
||||||
tree.Clear();
|
tree.Clear();
|
||||||
auto fend = m.faces_end();
|
auto fend = m.faces_end();
|
||||||
for(auto fit = m.faces_begin(); fit != fend; ++fit)
|
for (auto fit = m.faces_begin(); fit != fend; ++fit)
|
||||||
tree.Insert(Triangle(m,*fit));
|
tree.Insert(Triangle(m, *fit));
|
||||||
|
|
||||||
tree.Complete();
|
tree.Complete();
|
||||||
std::cout << "Done." << std::endl;
|
std::cout << "Done." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildAABBTreeFromVertices(const HEMesh& m, AABBTree<Point>& tree)
|
void BuildAABBTreeFromVertices(const HEMesh &m, AABBTree<Point> &tree)
|
||||||
{
|
{
|
||||||
std::cout << "Building AABB tree from vertices .." << std::endl;
|
std::cout << "Building AABB tree from vertices .." << std::endl;
|
||||||
tree.Clear();
|
tree.Clear();
|
||||||
auto vend = m.vertices_end();
|
auto vend = m.vertices_end();
|
||||||
for(auto vit = m.vertices_begin(); vit != vend; ++vit)
|
for (auto vit = m.vertices_begin(); vit != vend; ++vit)
|
||||||
tree.Insert(Point(m,*vit));
|
tree.Insert(Point(m, *vit));
|
||||||
|
|
||||||
tree.Complete();
|
tree.Complete();
|
||||||
std::cout << "Done." << std::endl;
|
std::cout << "Done." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildAABBTreeFromEdges(const HEMesh& m, AABBTree<LineSegment>& tree)
|
void BuildAABBTreeFromEdges(const HEMesh &m, AABBTree<LineSegment> &tree)
|
||||||
{
|
{
|
||||||
std::cout << "Building AABB tree from edges .." << std::endl;
|
std::cout << "Building AABB tree from edges .." << std::endl;
|
||||||
tree.Clear();
|
tree.Clear();
|
||||||
auto eend = m.edges_end();
|
auto eend = m.edges_end();
|
||||||
for(auto eit = m.edges_begin(); eit != eend; ++eit)
|
for (auto eit = m.edges_begin(); eit != eend; ++eit)
|
||||||
tree.Insert(LineSegment(m,*eit));
|
tree.Insert(LineSegment(m, *eit));
|
||||||
|
|
||||||
tree.Complete();
|
tree.Complete();
|
||||||
std::cout << "Done." << std::endl;
|
std::cout << "Done." << std::endl;
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "GridUtils.h"
|
#include "GridUtils.h"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
|
||||||
//creates an empty box like the method Clear
|
//creates an empty box like the method Clear
|
||||||
Box::Box()
|
Box::Box()
|
||||||
{
|
{
|
||||||
|
@ -14,31 +13,31 @@ Box::Box()
|
||||||
}
|
}
|
||||||
|
|
||||||
//construct a box with the gven lower and upper corner points
|
//construct a box with the gven lower and upper corner points
|
||||||
Box::Box(const Eigen::Vector3f& lbound, const Eigen::Vector3f& ubound)
|
Box::Box(const Eigen::Vector3f &lbound, const Eigen::Vector3f &ubound)
|
||||||
{
|
{
|
||||||
bounds = std::make_pair(lbound,ubound);
|
bounds = std::make_pair(lbound, ubound);
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the corner point which is the lower bound of the box in all dimensions
|
//returns the corner point which is the lower bound of the box in all dimensions
|
||||||
Eigen::Vector3f& Box::LowerBound()
|
Eigen::Vector3f &Box::LowerBound()
|
||||||
{
|
{
|
||||||
return bounds.first;
|
return bounds.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the corner point which is the lower bound of the box in all dimensions
|
//returns the corner point which is the lower bound of the box in all dimensions
|
||||||
const Eigen::Vector3f& Box::LowerBound() const
|
const Eigen::Vector3f &Box::LowerBound() const
|
||||||
{
|
{
|
||||||
return bounds.first;
|
return bounds.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the corner point which is the upper bound of the box in all dimensions
|
//returns the corner point which is the upper bound of the box in all dimensions
|
||||||
Eigen::Vector3f& Box::UpperBound()
|
Eigen::Vector3f &Box::UpperBound()
|
||||||
{
|
{
|
||||||
return bounds.second;
|
return bounds.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the corner point which is the upper bound of the box in all dimensions
|
//returns the corner point which is the upper bound of the box in all dimensions
|
||||||
const Eigen::Vector3f& Box::UpperBound() const
|
const Eigen::Vector3f &Box::UpperBound() const
|
||||||
{
|
{
|
||||||
return bounds.second;
|
return bounds.second;
|
||||||
}
|
}
|
||||||
|
@ -46,45 +45,45 @@ const Eigen::Vector3f& Box::UpperBound() const
|
||||||
//returns a vector containing the extents of the box in all dimensions
|
//returns a vector containing the extents of the box in all dimensions
|
||||||
Eigen::Vector3f Box::Extents() const
|
Eigen::Vector3f Box::Extents() const
|
||||||
{
|
{
|
||||||
return UpperBound()-LowerBound();
|
return UpperBound() - LowerBound();
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns a vector containing the extents of the box in all dimensions divided by 2
|
//returns a vector containing the extents of the box in all dimensions divided by 2
|
||||||
Eigen::Vector3f Box::HalfExtents() const
|
Eigen::Vector3f Box::HalfExtents() const
|
||||||
{
|
{
|
||||||
return Extents()/2.0f;
|
return Extents() / 2.0f;
|
||||||
}
|
}
|
||||||
//returns the center of the box
|
//returns the center of the box
|
||||||
Eigen::Vector3f Box::Center() const
|
Eigen::Vector3f Box::Center() const
|
||||||
{
|
{
|
||||||
return (LowerBound()+UpperBound())/2.0f;
|
return (LowerBound() + UpperBound()) / 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the surface area of the box
|
//returns the surface area of the box
|
||||||
float Box::SurfaceArea() const
|
float Box::SurfaceArea() const
|
||||||
{
|
{
|
||||||
Eigen::Vector3f e = Extents();
|
Eigen::Vector3f e = Extents();
|
||||||
return 2.0f*(e[0]*e[1] + e[1]*e[2] + e[0]*e[2]);
|
return 2.0f * (e[0] * e[1] + e[1] * e[2] + e[0] * e[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the volume of the box
|
//returns the volume of the box
|
||||||
float Box::Volume() const
|
float Box::Volume() const
|
||||||
{
|
{
|
||||||
Eigen::Vector3f e = Extents();
|
Eigen::Vector3f e = Extents();
|
||||||
return e[0] + e[1]+ e[2];
|
return e[0] + e[1] + e[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the box radius for a given direction vector a
|
//returns the box radius for a given direction vector a
|
||||||
//if the box is centered at the origin
|
//if the box is centered at the origin
|
||||||
//then the projection of the box on direction a is contained within the Interval [-r,r]
|
//then the projection of the box on direction a is contained within the Interval [-r,r]
|
||||||
float Box::Radius(const Eigen::Vector3f& a) const
|
float Box::Radius(const Eigen::Vector3f &a) const
|
||||||
{
|
{
|
||||||
Eigen::Vector3f h = HalfExtents();
|
Eigen::Vector3f h = HalfExtents();
|
||||||
return h[0]*std::abs(a[0]) + h[1]*std::abs(a[1]) + h[2]*std::abs(a[2]);
|
return h[0] * std::abs(a[0]) + h[1] * std::abs(a[1]) + h[2] * std::abs(a[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns true if the box b overlaps with the current one
|
//returns true if the box b overlaps with the current one
|
||||||
bool Box:: Overlaps(const Box& b) const
|
bool Box::Overlaps(const Box &b) const
|
||||||
{
|
{
|
||||||
Eigen::Vector3f lb1 = LowerBound();
|
Eigen::Vector3f lb1 = LowerBound();
|
||||||
Eigen::Vector3f ub1 = UpperBound();
|
Eigen::Vector3f ub1 = UpperBound();
|
||||||
|
@ -92,22 +91,22 @@ bool Box:: Overlaps(const Box& b) const
|
||||||
Eigen::Vector3f lb2 = b.LowerBound();
|
Eigen::Vector3f lb2 = b.LowerBound();
|
||||||
Eigen::Vector3f ub2 = b.UpperBound();
|
Eigen::Vector3f ub2 = b.UpperBound();
|
||||||
|
|
||||||
if(!OverlapIntervals(lb1[0], ub1[0],lb2[0], ub2[0]))
|
if (!OverlapIntervals(lb1[0], ub1[0], lb2[0], ub2[0]))
|
||||||
return false;
|
return false;
|
||||||
if(!OverlapIntervals(lb1[1], ub1[1],lb2[1], ub2[1]))
|
if (!OverlapIntervals(lb1[1], ub1[1], lb2[1], ub2[1]))
|
||||||
return false;
|
return false;
|
||||||
if(!OverlapIntervals(lb1[2], ub1[2],lb2[2], ub2[2]))
|
if (!OverlapIntervals(lb1[2], ub1[2], lb2[2], ub2[2]))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns true if the point p is inside this box
|
//returns true if the point p is inside this box
|
||||||
bool Box::IsInside(const Eigen::Vector3f& p) const
|
bool Box::IsInside(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
const Eigen::Vector3f& lbound = LowerBound();
|
const Eigen::Vector3f &lbound = LowerBound();
|
||||||
const Eigen::Vector3f& ubound = UpperBound();
|
const Eigen::Vector3f &ubound = UpperBound();
|
||||||
if(p[0] < lbound[0] || p[0] > ubound[0] ||
|
if (p[0] < lbound[0] || p[0] > ubound[0] ||
|
||||||
p[1] < lbound[1] || p[1] > ubound[1] ||
|
p[1] < lbound[1] || p[1] > ubound[1] ||
|
||||||
p[2] < lbound[2] || p[2] > ubound[2])
|
p[2] < lbound[2] || p[2] > ubound[2])
|
||||||
return false;
|
return false;
|
||||||
|
@ -115,7 +114,7 @@ bool Box::IsInside(const Eigen::Vector3f& p) const
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns true if box b is inside this box
|
//returns true if box b is inside this box
|
||||||
bool Box::IsInside(const Box& b) const
|
bool Box::IsInside(const Box &b) const
|
||||||
{
|
{
|
||||||
return IsInside(b.LowerBound()) && IsInside(b.UpperBound());
|
return IsInside(b.LowerBound()) && IsInside(b.UpperBound());
|
||||||
}
|
}
|
||||||
|
@ -124,55 +123,53 @@ bool Box::IsInside(const Box& b) const
|
||||||
void Box::Clear()
|
void Box::Clear()
|
||||||
{
|
{
|
||||||
const float infty = std::numeric_limits<float>::infinity();
|
const float infty = std::numeric_limits<float>::infinity();
|
||||||
const Eigen::Vector3f vec_infty = Eigen::Vector3f(infty,infty,infty);
|
const Eigen::Vector3f vec_infty = Eigen::Vector3f(infty, infty, infty);
|
||||||
bounds = std::make_pair(vec_infty,-vec_infty);
|
bounds = std::make_pair(vec_infty, -vec_infty);
|
||||||
}
|
}
|
||||||
|
|
||||||
//enlarges the box such that the point p is inside afterwards
|
//enlarges the box such that the point p is inside afterwards
|
||||||
void Box::Insert(const Eigen::Vector3f& p)
|
void Box::Insert(const Eigen::Vector3f &p)
|
||||||
{
|
{
|
||||||
Eigen::Vector3f& lbound = LowerBound();
|
Eigen::Vector3f &lbound = LowerBound();
|
||||||
Eigen::Vector3f& ubound = UpperBound();
|
Eigen::Vector3f &ubound = UpperBound();
|
||||||
lbound[0] = (std::min)(p[0],lbound[0]);
|
lbound[0] = (std::min)(p[0], lbound[0]);
|
||||||
lbound[1] = (std::min)(p[1],lbound[1]);
|
lbound[1] = (std::min)(p[1], lbound[1]);
|
||||||
lbound[2] = (std::min)(p[2],lbound[2]);
|
lbound[2] = (std::min)(p[2], lbound[2]);
|
||||||
ubound[0] = (std::max)(p[0],ubound[0]);
|
ubound[0] = (std::max)(p[0], ubound[0]);
|
||||||
ubound[1] = (std::max)(p[1],ubound[1]);
|
ubound[1] = (std::max)(p[1], ubound[1]);
|
||||||
ubound[2] = (std::max)(p[2],ubound[2]);
|
ubound[2] = (std::max)(p[2], ubound[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//enlarges the box such that box b is inside afterwards
|
//enlarges the box such that box b is inside afterwards
|
||||||
void Box::Insert(const Box& b)
|
void Box::Insert(const Box &b)
|
||||||
{
|
{
|
||||||
Insert(b.LowerBound());
|
Insert(b.LowerBound());
|
||||||
Insert(b.UpperBound());
|
Insert(b.UpperBound());
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the point on or inside the box with the smallest distance to p
|
//returns the point on or inside the box with the smallest distance to p
|
||||||
Eigen::Vector3f Box::ClosestPoint(const Eigen::Vector3f& p) const
|
Eigen::Vector3f Box::ClosestPoint(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
Eigen::Vector3f q;
|
Eigen::Vector3f q;
|
||||||
const Eigen::Vector3f& lbound = LowerBound();
|
const Eigen::Vector3f &lbound = LowerBound();
|
||||||
const Eigen::Vector3f& ubound = UpperBound();
|
const Eigen::Vector3f &ubound = UpperBound();
|
||||||
|
|
||||||
q[0] = std::min(std::max(p[0],lbound[0]),ubound[0]);
|
q[0] = std::min(std::max(p[0], lbound[0]), ubound[0]);
|
||||||
q[1] = std::min(std::max(p[1],lbound[1]),ubound[1]);
|
q[1] = std::min(std::max(p[1], lbound[1]), ubound[1]);
|
||||||
q[2] = std::min(std::max(p[2],lbound[2]),ubound[2]);
|
q[2] = std::min(std::max(p[2], lbound[2]), ubound[2]);
|
||||||
|
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the squared distance between p and the box
|
//returns the squared distance between p and the box
|
||||||
float Box::SqrDistance(const Eigen::Vector3f& p) const
|
float Box::SqrDistance(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
Eigen::Vector3f d = p-ClosestPoint(p);
|
Eigen::Vector3f d = p - ClosestPoint(p);
|
||||||
return d.dot(d);
|
return d.dot(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the euclidean distance between p and the box
|
//returns the euclidean distance between p and the box
|
||||||
float Box::Distance(const Eigen::Vector3f& p) const
|
float Box::Distance(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
return sqrt(SqrDistance(p));
|
return sqrt(SqrDistance(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,37 +5,37 @@
|
||||||
#include "GridTraverser.h"
|
#include "GridTraverser.h"
|
||||||
#include "GridUtils.h"
|
#include "GridUtils.h"
|
||||||
|
|
||||||
|
|
||||||
GridTraverser::GridTraverser()
|
GridTraverser::GridTraverser()
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
|
|
||||||
GridTraverser::GridTraverser(const Eigen::Vector3f& o, const Eigen::Vector3f&d, const Eigen::Vector3f cell_extents)
|
GridTraverser::GridTraverser(const Eigen::Vector3f &o, const Eigen::Vector3f &d, const Eigen::Vector3f cell_extents)
|
||||||
: orig(o), dir(d), cellExtents(cell_extents)
|
: orig(o), dir(d), cellExtents(cell_extents)
|
||||||
{
|
{
|
||||||
dir.normalize();
|
dir.normalize();
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
Eigen::Vector3f& GridTraverser::Origin()
|
Eigen::Vector3f &GridTraverser::Origin()
|
||||||
{
|
{
|
||||||
return orig;
|
return orig;
|
||||||
}
|
}
|
||||||
const Eigen::Vector3f& GridTraverser::Origin() const
|
const Eigen::Vector3f &GridTraverser::Origin() const
|
||||||
{
|
{
|
||||||
return orig;
|
return orig;
|
||||||
}
|
}
|
||||||
|
|
||||||
Eigen::Vector3f& GridTraverser::Direction()
|
Eigen::Vector3f &GridTraverser::Direction()
|
||||||
{
|
{
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Eigen::Vector3f& GridTraverser::Direction() const
|
const Eigen::Vector3f &GridTraverser::Direction() const
|
||||||
{
|
{
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GridTraverser::SetCellExtents(const Eigen::Vector3f& cellExtent)
|
void GridTraverser::SetCellExtents(const Eigen::Vector3f &cellExtent)
|
||||||
{
|
{
|
||||||
this->cellExtents = cellExtent;
|
this->cellExtents = cellExtent;
|
||||||
Init();
|
Init();
|
||||||
|
@ -59,5 +59,3 @@ Eigen::Vector3i GridTraverser::operator*()
|
||||||
{
|
{
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,32 +5,32 @@
|
||||||
#include "HashGrid.h"
|
#include "HashGrid.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
void BuildHashGridFromTriangles(const HEMesh& m, HashGrid<Triangle>& grid, const Eigen::Vector3f& cellSize)
|
void BuildHashGridFromTriangles(const HEMesh &m, HashGrid<Triangle> &grid, const Eigen::Vector3f &cellSize)
|
||||||
{
|
{
|
||||||
std::cout << "Building hash grid from triangles .." << std::endl;
|
std::cout << "Building hash grid from triangles .." << std::endl;
|
||||||
grid = HashGrid<Triangle>(cellSize, 1);
|
grid = HashGrid<Triangle>(cellSize, 1);
|
||||||
auto fend = m.faces_end();
|
auto fend = m.faces_end();
|
||||||
for(auto fit = m.faces_begin(); fit != fend; ++fit)
|
for (auto fit = m.faces_begin(); fit != fend; ++fit)
|
||||||
grid.Insert(Triangle(m,*fit));
|
grid.Insert(Triangle(m, *fit));
|
||||||
std::cout << "Done (using " << grid.NumCells() << " cells)." << std::endl;
|
std::cout << "Done (using " << grid.NumCells() << " cells)." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildHashGridFromVertices(const HEMesh& m, HashGrid<Point>& grid, const Eigen::Vector3f& cellSize)
|
void BuildHashGridFromVertices(const HEMesh &m, HashGrid<Point> &grid, const Eigen::Vector3f &cellSize)
|
||||||
{
|
{
|
||||||
std::cout << "Building hash grid from vertices .." << std::endl;
|
std::cout << "Building hash grid from vertices .." << std::endl;
|
||||||
grid = HashGrid<Point>(cellSize, 1);
|
grid = HashGrid<Point>(cellSize, 1);
|
||||||
auto vend = m.vertices_end();
|
auto vend = m.vertices_end();
|
||||||
for(auto vit = m.vertices_begin(); vit != vend; ++vit)
|
for (auto vit = m.vertices_begin(); vit != vend; ++vit)
|
||||||
grid.Insert(Point(m,*vit));
|
grid.Insert(Point(m, *vit));
|
||||||
std::cout << "Done (using " << grid.NumCells() << " cells)." << std::endl;
|
std::cout << "Done (using " << grid.NumCells() << " cells)." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildHashGridFromEdges(const HEMesh& m, HashGrid<LineSegment >& grid, const Eigen::Vector3f& cellSize)
|
void BuildHashGridFromEdges(const HEMesh &m, HashGrid<LineSegment> &grid, const Eigen::Vector3f &cellSize)
|
||||||
{
|
{
|
||||||
std::cout << "Building hash grid from edges .." << std::endl;
|
std::cout << "Building hash grid from edges .." << std::endl;
|
||||||
grid = HashGrid<LineSegment>(cellSize, 1);
|
grid = HashGrid<LineSegment>(cellSize, 1);
|
||||||
auto eend = m.edges_end();
|
auto eend = m.edges_end();
|
||||||
for(auto eit = m.edges_begin(); eit != eend; ++eit)
|
for (auto eit = m.edges_begin(); eit != eend; ++eit)
|
||||||
grid.Insert(LineSegment(m,*eit));
|
grid.Insert(LineSegment(m, *eit));
|
||||||
std::cout << "Done (using " << grid.NumCells() << " cells)." << std::endl;
|
std::cout << "Done (using " << grid.NumCells() << " cells)." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,19 +5,18 @@
|
||||||
#include "LineSegment.h"
|
#include "LineSegment.h"
|
||||||
#include "GridUtils.h"
|
#include "GridUtils.h"
|
||||||
|
|
||||||
|
|
||||||
//default constructor
|
//default constructor
|
||||||
LineSegment::LineSegment()
|
LineSegment::LineSegment()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//constructs a line segment by the two end points v0, v1 without using the edge handle
|
//constructs a line segment by the two end points v0, v1 without using the edge handle
|
||||||
LineSegment::LineSegment(const Eigen::Vector3f& v0, const Eigen::Vector3f& v1):v0(v0),v1(v1)
|
LineSegment::LineSegment(const Eigen::Vector3f &v0, const Eigen::Vector3f &v1) : v0(v0), v1(v1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//construct a line segment from the edge e of the halfedge mesh m
|
//construct a line segment from the edge e of the halfedge mesh m
|
||||||
LineSegment::LineSegment(const HEMesh& m,const OpenMesh::EdgeHandle& e):h(e)
|
LineSegment::LineSegment(const HEMesh &m, const OpenMesh::EdgeHandle &e) : h(e)
|
||||||
{
|
{
|
||||||
auto h = m.halfedge_handle(e, 0);
|
auto h = m.halfedge_handle(e, 0);
|
||||||
v0 = ToEigenVector(m.point(m.from_vertex_handle(h)));
|
v0 = ToEigenVector(m.point(m.from_vertex_handle(h)));
|
||||||
|
@ -34,81 +33,78 @@ Box LineSegment::ComputeBounds() const
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns true if the line segment overlaps the given box b
|
//returns true if the line segment overlaps the given box b
|
||||||
bool LineSegment::Overlaps(const Box& b) const
|
bool LineSegment::Overlaps(const Box &b) const
|
||||||
{
|
{
|
||||||
|
|
||||||
Box aabb = ComputeBounds();
|
Box aabb = ComputeBounds();
|
||||||
|
|
||||||
if(!b.Overlaps(aabb))
|
if (!b.Overlaps(aabb))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Eigen::Vector3f o = b.Center();
|
Eigen::Vector3f o = b.Center();
|
||||||
Eigen::Vector3f u1 = v0-o;
|
Eigen::Vector3f u1 = v0 - o;
|
||||||
Eigen::Vector3f u2 = v1-o;
|
Eigen::Vector3f u2 = v1 - o;
|
||||||
|
|
||||||
Eigen::Vector3f d1 = v1-v0;
|
Eigen::Vector3f d1 = v1 - v0;
|
||||||
d1.normalize();
|
d1.normalize();
|
||||||
|
|
||||||
float r = b.Radius(d1);
|
float r = b.Radius(d1);
|
||||||
float lb = u1.dot(d1);
|
float lb = u1.dot(d1);
|
||||||
float ub = u2.dot(d1);
|
float ub = u2.dot(d1);
|
||||||
if(lb > ub)
|
if (lb > ub)
|
||||||
std::swap(lb,ub);
|
std::swap(lb, ub);
|
||||||
if(lb > r || ub < -r)
|
if (lb > r || ub < -r)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Eigen::Vector3f e1(1,0,0);
|
Eigen::Vector3f e1(1, 0, 0);
|
||||||
Eigen::Vector3f d2= d1.cross(e1);
|
Eigen::Vector3f d2 = d1.cross(e1);
|
||||||
r = b.Radius(d2);
|
r = b.Radius(d2);
|
||||||
lb = u1.dot(d2);
|
lb = u1.dot(d2);
|
||||||
ub = u2.dot(d2);
|
ub = u2.dot(d2);
|
||||||
if(lb > ub)
|
if (lb > ub)
|
||||||
std::swap(lb,ub);
|
std::swap(lb, ub);
|
||||||
if(!OverlapIntervals(-r,r,lb,ub))
|
if (!OverlapIntervals(-r, r, lb, ub))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Eigen::Vector3f e2(0,1,0);
|
Eigen::Vector3f e2(0, 1, 0);
|
||||||
Eigen::Vector3f d3 = d1.cross(e2);
|
Eigen::Vector3f d3 = d1.cross(e2);
|
||||||
r = b.Radius(d3);
|
r = b.Radius(d3);
|
||||||
lb = u1.dot(d3);
|
lb = u1.dot(d3);
|
||||||
ub = u2.dot(d3);
|
ub = u2.dot(d3);
|
||||||
if(lb > ub)
|
if (lb > ub)
|
||||||
std::swap(lb,ub);
|
std::swap(lb, ub);
|
||||||
if(!OverlapIntervals(-r,r,lb,ub))
|
if (!OverlapIntervals(-r, r, lb, ub))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Eigen::Vector3f e3(0,0,1);
|
Eigen::Vector3f e3(0, 0, 1);
|
||||||
Eigen::Vector3f d4 = d1.cross(e3);
|
Eigen::Vector3f d4 = d1.cross(e3);
|
||||||
r = b.Radius(d4);
|
r = b.Radius(d4);
|
||||||
lb = u1.dot(d4);
|
lb = u1.dot(d4);
|
||||||
ub = u2.dot(d4);
|
ub = u2.dot(d4);
|
||||||
|
|
||||||
if(!OverlapIntervals(-r,r,lb,ub))
|
if (!OverlapIntervals(-r, r, lb, ub))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the point with smallest distance topoint p which lies on the line segment
|
//returns the point with smallest distance topoint p which lies on the line segment
|
||||||
Eigen::Vector3f LineSegment::ClosestPoint(const Eigen::Vector3f& p) const
|
Eigen::Vector3f LineSegment::ClosestPoint(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
//the two endpoints of the line segment are v0,v1
|
//the two endpoints of the line segment are v0,v1
|
||||||
/* Task 3.2.1 */
|
/* Task 3.2.1 */
|
||||||
return Eigen::Vector3f(0,0,0);
|
return Eigen::Vector3f(0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the squared distance between point p and the line segment
|
//returns the squared distance between point p and the line segment
|
||||||
float LineSegment::SqrDistance(const Eigen::Vector3f& p) const
|
float LineSegment::SqrDistance(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
Eigen::Vector3f d = p-ClosestPoint(p);
|
Eigen::Vector3f d = p - ClosestPoint(p);
|
||||||
return d.squaredNorm();
|
return d.squaredNorm();
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the euclidean distance between point p and the line segment
|
//returns the euclidean distance between point p and the line segment
|
||||||
float LineSegment::Distance(const Eigen::Vector3f& p) const
|
float LineSegment::Distance(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
return sqrt(SqrDistance(p));
|
return sqrt(SqrDistance(p));
|
||||||
}
|
}
|
||||||
|
@ -116,8 +112,5 @@ float LineSegment::Distance(const Eigen::Vector3f& p) const
|
||||||
//returns a reference point which is on the line segment and is used to sort the primitive in the AABB tree construction
|
//returns a reference point which is on the line segment and is used to sort the primitive in the AABB tree construction
|
||||||
Eigen::Vector3f LineSegment::ReferencePoint() const
|
Eigen::Vector3f LineSegment::ReferencePoint() const
|
||||||
{
|
{
|
||||||
return 0.5f*(v0 + v1);
|
return 0.5f * (v0 + v1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,15 +6,15 @@
|
||||||
#include "GridUtils.h"
|
#include "GridUtils.h"
|
||||||
|
|
||||||
//default constructor
|
//default constructor
|
||||||
Point::Point(){}
|
Point::Point() {}
|
||||||
|
|
||||||
//construct a point with given point position v0
|
//construct a point with given point position v0
|
||||||
Point::Point(const Eigen::Vector3f& v0):v0(v0)
|
Point::Point(const Eigen::Vector3f &v0) : v0(v0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//construct a point from vertex v of giben halfedge mesh m
|
//construct a point from vertex v of giben halfedge mesh m
|
||||||
Point::Point(const HEMesh &m, const OpenMesh::VertexHandle& v):h(v)
|
Point::Point(const HEMesh &m, const OpenMesh::VertexHandle &v) : h(v)
|
||||||
{
|
{
|
||||||
v0 = ToEigenVector(m.point(v));
|
v0 = ToEigenVector(m.point(v));
|
||||||
}
|
}
|
||||||
|
@ -29,31 +29,30 @@ Box Point::ComputeBounds() const
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns true if point overlap with box b
|
//returns true if point overlap with box b
|
||||||
bool Point::Overlaps(const Box& b) const
|
bool Point::Overlaps(const Box &b) const
|
||||||
{
|
{
|
||||||
Eigen::Vector3f lb = b.LowerBound();
|
Eigen::Vector3f lb = b.LowerBound();
|
||||||
Eigen::Vector3f ub = b.UpperBound();
|
Eigen::Vector3f ub = b.UpperBound();
|
||||||
return
|
return (v0[0] >= lb[0] && v0[0] <= ub[0] &&
|
||||||
(v0[0] >= lb[0] && v0[0] <= ub[0]&&
|
v0[1] >= lb[1] && v0[1] <= ub[1] &&
|
||||||
v0[1] >= lb[1] && v0[1] <= ub[1] &&
|
v0[2] >= lb[2] && v0[2] <= ub[2]);
|
||||||
v0[2] >= lb[2] && v0[2] <= ub[2]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the point position
|
//returns the point position
|
||||||
Eigen::Vector3f Point::ClosestPoint(const Eigen::Vector3f& p) const
|
Eigen::Vector3f Point::ClosestPoint(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
return v0;
|
return v0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the squared distance between the query point p and the current point
|
//returns the squared distance between the query point p and the current point
|
||||||
float Point::SqrDistance(const Eigen::Vector3f& p) const
|
float Point::SqrDistance(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
Eigen::Vector3f d = p-ClosestPoint(p);
|
Eigen::Vector3f d = p - ClosestPoint(p);
|
||||||
return d.squaredNorm();
|
return d.squaredNorm();
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns the euclidean distance between the query point p and the current point
|
//returns the euclidean distance between the query point p and the current point
|
||||||
float Point::Distance(const Eigen::Vector3f& p) const
|
float Point::Distance(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
return sqrt(SqrDistance(p));
|
return sqrt(SqrDistance(p));
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,17 +6,16 @@
|
||||||
#include "GridUtils.h"
|
#include "GridUtils.h"
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
|
|
||||||
//default constructor
|
//default constructor
|
||||||
Triangle::Triangle()
|
Triangle::Triangle()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
//constructs a triangle using the vertex positions v0,v1 and v2
|
//constructs a triangle using the vertex positions v0,v1 and v2
|
||||||
Triangle::Triangle(const Eigen::Vector3f& v0, const Eigen::Vector3f& v1,const Eigen::Vector3f& v2): v0(v0),v1(v1),v2(v2)
|
Triangle::Triangle(const Eigen::Vector3f &v0, const Eigen::Vector3f &v1, const Eigen::Vector3f &v2) : v0(v0), v1(v1), v2(v2)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
//constructs a triangle from the face f of the given halfedge mesh m
|
//constructs a triangle from the face f of the given halfedge mesh m
|
||||||
Triangle::Triangle(const HEMesh&m, const OpenMesh::FaceHandle& f):h(f)
|
Triangle::Triangle(const HEMesh &m, const OpenMesh::FaceHandle &f) : h(f)
|
||||||
{
|
{
|
||||||
OpenMesh::HalfedgeHandle he = m.halfedge_handle(f);
|
OpenMesh::HalfedgeHandle he = m.halfedge_handle(f);
|
||||||
v0 = ToEigenVector(m.point(m.from_vertex_handle(he)));
|
v0 = ToEigenVector(m.point(m.from_vertex_handle(he)));
|
||||||
|
@ -33,62 +32,60 @@ Box Triangle::ComputeBounds() const
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//returns true if the triangle overlaps the given box b
|
//returns true if the triangle overlaps the given box b
|
||||||
bool Triangle::Overlaps(const Box& b) const
|
bool Triangle::Overlaps(const Box &b) const
|
||||||
{
|
{
|
||||||
/* Task 3.2.2 */
|
/* Task 3.2.2 */
|
||||||
//carefully look at the interface of the box class, there might be a lot of useful helper functions
|
//carefully look at the interface of the box class, there might be a lot of useful helper functions
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//returns the barycentric coordinates of the point with the smallest distance to point p which lies on the triangle
|
//returns the barycentric coordinates of the point with the smallest distance to point p which lies on the triangle
|
||||||
void Triangle::ClosestPointBarycentric(const Eigen::Vector3f& p, float& l0, float& l1, float& l2) const
|
void Triangle::ClosestPointBarycentric(const Eigen::Vector3f &p, float &l0, float &l1, float &l2) const
|
||||||
{
|
{
|
||||||
Eigen::Vector3f edge0 = v1 - v0;
|
Eigen::Vector3f edge0 = v1 - v0;
|
||||||
Eigen::Vector3f edge1 = v2 - v0;
|
Eigen::Vector3f edge1 = v2 - v0;
|
||||||
Eigen::Vector3f v = v0 - p;
|
Eigen::Vector3f v = v0 - p;
|
||||||
|
|
||||||
float a = edge0.dot( edge0 );
|
float a = edge0.dot(edge0);
|
||||||
float b = edge0.dot( edge1 );
|
float b = edge0.dot(edge1);
|
||||||
float c = edge1.dot( edge1 );
|
float c = edge1.dot(edge1);
|
||||||
float d = edge0.dot( v );
|
float d = edge0.dot(v);
|
||||||
float e = edge1.dot( v );
|
float e = edge1.dot(v);
|
||||||
|
|
||||||
float det = a*c - b*b;
|
float det = a * c - b * b;
|
||||||
float s = b*e - c*d;
|
float s = b * e - c * d;
|
||||||
float t = b*d - a*e;
|
float t = b * d - a * e;
|
||||||
|
|
||||||
if ( s + t < det )
|
if (s + t < det)
|
||||||
{
|
{
|
||||||
if ( s < 0.f )
|
if (s < 0.f)
|
||||||
{
|
{
|
||||||
if ( t < 0.f )
|
if (t < 0.f)
|
||||||
{
|
{
|
||||||
if ( d < 0.f )
|
if (d < 0.f)
|
||||||
{
|
{
|
||||||
s=-d/a;
|
s = -d / a;
|
||||||
s=std::min(std::max(s,0.0f),1.0f);
|
s = std::min(std::max(s, 0.0f), 1.0f);
|
||||||
t = 0.f;
|
t = 0.f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s = 0.f;
|
s = 0.f;
|
||||||
t = -e/c;
|
t = -e / c;
|
||||||
t = std::min(std::max(t,0.0f),1.0f);
|
t = std::min(std::max(t, 0.0f), 1.0f);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s = 0.f;
|
s = 0.f;
|
||||||
t = -e/c;
|
t = -e / c;
|
||||||
t = std::min(std::max(t,0.0f),1.0f);
|
t = std::min(std::max(t, 0.0f), 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( t < 0.f )
|
else if (t < 0.f)
|
||||||
{
|
{
|
||||||
s = -d/a;
|
s = -d / a;
|
||||||
s=std::min(std::max(s,0.0f),1.0f);
|
s = std::min(std::max(s, 0.0f), 1.0f);
|
||||||
t = 0.f;
|
t = 0.f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -100,81 +97,77 @@ void Triangle::ClosestPointBarycentric(const Eigen::Vector3f& p, float& l0, floa
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( s < 0.f )
|
if (s < 0.f)
|
||||||
{
|
{
|
||||||
float tmp0 = b+d;
|
float tmp0 = b + d;
|
||||||
float tmp1 = c+e;
|
float tmp1 = c + e;
|
||||||
if ( tmp1 > tmp0 )
|
if (tmp1 > tmp0)
|
||||||
{
|
{
|
||||||
float numer = tmp1 - tmp0;
|
float numer = tmp1 - tmp0;
|
||||||
float denom = a-2*b+c;
|
float denom = a - 2 * b + c;
|
||||||
s = numer/denom;
|
s = numer / denom;
|
||||||
s=std::min(std::max(s,0.0f),1.0f);
|
s = std::min(std::max(s, 0.0f), 1.0f);
|
||||||
t = 1-s;
|
t = 1 - s;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
t = -e/c;
|
t = -e / c;
|
||||||
t=std::min(std::max(t,0.0f),1.0f);
|
t = std::min(std::max(t, 0.0f), 1.0f);
|
||||||
s = 0.f;
|
s = 0.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( t < 0.f )
|
else if (t < 0.f)
|
||||||
{
|
{
|
||||||
if ( a+d > b+e )
|
if (a + d > b + e)
|
||||||
{
|
{
|
||||||
float numer = c+e-b-d;
|
float numer = c + e - b - d;
|
||||||
float denom = a-2*b+c;
|
float denom = a - 2 * b + c;
|
||||||
s = numer/denom;
|
s = numer / denom;
|
||||||
s=std::min(std::max(s,0.0f),1.0f);
|
s = std::min(std::max(s, 0.0f), 1.0f);
|
||||||
|
|
||||||
t = 1-s;
|
t = 1 - s;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s = -e/c;
|
s = -e / c;
|
||||||
s=std::min(std::max(s,0.0f),1.0f);
|
s = std::min(std::max(s, 0.0f), 1.0f);
|
||||||
t = 0.f;
|
t = 0.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float numer = c+e-b-d;
|
float numer = c + e - b - d;
|
||||||
float denom = a-2*b+c;
|
float denom = a - 2 * b + c;
|
||||||
|
|
||||||
s = numer/denom;
|
s = numer / denom;
|
||||||
s=std::min(std::max(s,0.0f),1.0f);
|
s = std::min(std::max(s, 0.0f), 1.0f);
|
||||||
t = 1.f - s;
|
t = 1.f - s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
l0 = 1-s-t;
|
l0 = 1 - s - t;
|
||||||
l1 = s;
|
l1 = s;
|
||||||
l2 = t;
|
l2 = t;
|
||||||
}
|
}
|
||||||
//returns the point with smallest distance to point p which lies on the triangle
|
//returns the point with smallest distance to point p which lies on the triangle
|
||||||
Eigen::Vector3f Triangle::ClosestPoint(const Eigen::Vector3f& p) const
|
Eigen::Vector3f Triangle::ClosestPoint(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
float l0,l1,l2;
|
float l0, l1, l2;
|
||||||
ClosestPointBarycentric(p,l0,l1,l2);
|
ClosestPointBarycentric(p, l0, l1, l2);
|
||||||
return l0*v0 + l1*v1 +l2* v2;
|
return l0 * v0 + l1 * v1 + l2 * v2;
|
||||||
|
|
||||||
}
|
}
|
||||||
//returns the squared distance between point p and the triangle
|
//returns the squared distance between point p and the triangle
|
||||||
float Triangle::SqrDistance(const Eigen::Vector3f& p) const
|
float Triangle::SqrDistance(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
Eigen::Vector3f d = p-ClosestPoint(p);
|
Eigen::Vector3f d = p - ClosestPoint(p);
|
||||||
return d.squaredNorm();
|
return d.squaredNorm();
|
||||||
}
|
}
|
||||||
//returns the euclidean distance between point p and the triangle
|
//returns the euclidean distance between point p and the triangle
|
||||||
float Triangle::Distance(const Eigen::Vector3f& p) const
|
float Triangle::Distance(const Eigen::Vector3f &p) const
|
||||||
{
|
{
|
||||||
return sqrt(SqrDistance(p));
|
return sqrt(SqrDistance(p));
|
||||||
}
|
}
|
||||||
//returns a reference point which is on the triangle and is used to sort the primitive in the AABB tree construction
|
//returns a reference point which is on the triangle and is used to sort the primitive in the AABB tree construction
|
||||||
Eigen::Vector3f Triangle::ReferencePoint() const
|
Eigen::Vector3f Triangle::ReferencePoint() const
|
||||||
{
|
{
|
||||||
return (v0+v1+v2)/3.0f;
|
return (v0 + v1 + v2) / 3.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,10 @@
|
||||||
|
|
||||||
Viewer::Viewer()
|
Viewer::Viewer()
|
||||||
: AbstractViewer("CG1 Exercise 3"),
|
: AbstractViewer("CG1 Exercise 3"),
|
||||||
renderer(polymesh),
|
renderer(polymesh),
|
||||||
closestPositions(nse::gui::VertexBuffer),
|
closestPositions(nse::gui::VertexBuffer),
|
||||||
gridPositions(nse::gui::VertexBuffer),
|
gridPositions(nse::gui::VertexBuffer),
|
||||||
rayPositions(nse::gui::VertexBuffer), rayCellsPositions(nse::gui::VertexBuffer)
|
rayPositions(nse::gui::VertexBuffer), rayCellsPositions(nse::gui::VertexBuffer)
|
||||||
{
|
{
|
||||||
SetupGUI();
|
SetupGUI();
|
||||||
|
|
||||||
|
@ -52,21 +52,21 @@ void Viewer::SetupGUI()
|
||||||
if (!OpenMesh::IO::read_mesh(polymesh, file))
|
if (!OpenMesh::IO::read_mesh(polymesh, file))
|
||||||
{
|
{
|
||||||
new nanogui::MessageDialog(this, nanogui::MessageDialog::Type::Warning, "Load Mesh",
|
new nanogui::MessageDialog(this, nanogui::MessageDialog::Type::Warning, "Load Mesh",
|
||||||
"The specified file could not be loaded");
|
"The specified file could not be loaded");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
MeshUpdated();
|
MeshUpdated();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
cmbPrimitiveType = new nanogui::ComboBox(mainWindow, { "Use Vertices", "Use Edges", "Use Triangles" });
|
cmbPrimitiveType = new nanogui::ComboBox(mainWindow, {"Use Vertices", "Use Edges", "Use Triangles"});
|
||||||
cmbPrimitiveType->setCallback([this](int) { FindClosestPoint(sldQuery->Value()); BuildGridVBO(); });
|
cmbPrimitiveType->setCallback([this](int) { FindClosestPoint(sldQuery->Value()); BuildGridVBO(); });
|
||||||
|
|
||||||
sldQuery = new nse::gui::VectorInput(mainWindow, "Query", Eigen::Vector3f::Zero(), Eigen::Vector3f::Zero(), Eigen::Vector3f::Zero(), [this](const Eigen::Vector3f& p) { FindClosestPoint(p); });
|
sldQuery = new nse::gui::VectorInput(mainWindow, "Query", Eigen::Vector3f::Zero(), Eigen::Vector3f::Zero(), Eigen::Vector3f::Zero(), [this](const Eigen::Vector3f &p) { FindClosestPoint(p); });
|
||||||
|
|
||||||
sldRayOrigin = new nse::gui::VectorInput(mainWindow, "Ray Origin", Eigen::Vector3f::Zero(), Eigen::Vector3f::Zero(), Eigen::Vector3f::Zero(), [this](const Eigen::Vector3f& p) { BuildRayVBOs(); });
|
sldRayOrigin = new nse::gui::VectorInput(mainWindow, "Ray Origin", Eigen::Vector3f::Zero(), Eigen::Vector3f::Zero(), Eigen::Vector3f::Zero(), [this](const Eigen::Vector3f &p) { BuildRayVBOs(); });
|
||||||
sldRayDir = new nse::gui::VectorInput(mainWindow, "Ray Direction", Eigen::Vector3f::Constant(-1), Eigen::Vector3f::Constant(1), Eigen::Vector3f::Zero(), [this](const Eigen::Vector3f& p) { BuildRayVBOs(); });
|
sldRayDir = new nse::gui::VectorInput(mainWindow, "Ray Direction", Eigen::Vector3f::Constant(-1), Eigen::Vector3f::Constant(1), Eigen::Vector3f::Zero(), [this](const Eigen::Vector3f &p) { BuildRayVBOs(); });
|
||||||
nanogui::TextBox* txtRaySteps;
|
nanogui::TextBox *txtRaySteps;
|
||||||
auto sldRaySteps = nse::gui::AddLabeledSlider(mainWindow, "Ray Steps", std::make_pair(1, 200), 80, txtRaySteps);
|
auto sldRaySteps = nse::gui::AddLabeledSlider(mainWindow, "Ray Steps", std::make_pair(1, 200), 80, txtRaySteps);
|
||||||
sldRaySteps->setCallback([this, txtRaySteps](float value) {
|
sldRaySteps->setCallback([this, txtRaySteps](float value) {
|
||||||
raySteps = (int)std::round(value);
|
raySteps = (int)std::round(value);
|
||||||
|
@ -75,16 +75,19 @@ void Viewer::SetupGUI()
|
||||||
});
|
});
|
||||||
sldRaySteps->callback()(sldRaySteps->value());
|
sldRaySteps->callback()(sldRaySteps->value());
|
||||||
|
|
||||||
chkRenderMesh = new nanogui::CheckBox(mainWindow, "Render Mesh"); chkRenderMesh->setChecked(true);
|
chkRenderMesh = new nanogui::CheckBox(mainWindow, "Render Mesh");
|
||||||
chkRenderGrid = new nanogui::CheckBox(mainWindow, "Render Non-Empty Grid Cells"); chkRenderGrid->setChecked(false);
|
chkRenderMesh->setChecked(true);
|
||||||
chkRenderRay = new nanogui::CheckBox(mainWindow, "Render Ray"); chkRenderRay->setChecked(false);
|
chkRenderGrid = new nanogui::CheckBox(mainWindow, "Render Non-Empty Grid Cells");
|
||||||
|
chkRenderGrid->setChecked(false);
|
||||||
|
chkRenderRay = new nanogui::CheckBox(mainWindow, "Render Ray");
|
||||||
|
chkRenderRay->setChecked(false);
|
||||||
|
|
||||||
shadingBtn = new nanogui::ComboBox(mainWindow, { "Smooth Shading", "Flat Shading" });
|
shadingBtn = new nanogui::ComboBox(mainWindow, {"Smooth Shading", "Flat Shading"});
|
||||||
|
|
||||||
performLayout();
|
performLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::FindClosestPoint(const Eigen::Vector3f& p)
|
void Viewer::FindClosestPoint(const Eigen::Vector3f &p)
|
||||||
{
|
{
|
||||||
if (polymesh.vertices_empty())
|
if (polymesh.vertices_empty())
|
||||||
return;
|
return;
|
||||||
|
@ -196,14 +199,18 @@ void Viewer::BuildRayVBOs()
|
||||||
rayCellsIndices = (GLuint)cellPositions.size();
|
rayCellsIndices = (GLuint)cellPositions.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::AddBoxVertices(const Box & box, std::vector<Eigen::Vector4f>& positions)
|
void Viewer::AddBoxVertices(const Box &box, std::vector<Eigen::Vector4f> &positions)
|
||||||
{
|
{
|
||||||
auto& lb = box.LowerBound();
|
auto &lb = box.LowerBound();
|
||||||
auto& ub = box.UpperBound();
|
auto &ub = box.UpperBound();
|
||||||
Eigen::Vector4f o; o << lb, 1.0f;
|
Eigen::Vector4f o;
|
||||||
Eigen::Vector4f x; x << ub.x() - lb.x(), 0, 0, 0;
|
o << lb, 1.0f;
|
||||||
Eigen::Vector4f y; y << 0, ub.y() - lb.y(), 0, 0;
|
Eigen::Vector4f x;
|
||||||
Eigen::Vector4f z; z << 0, 0, ub.z() - lb.z(), 0;
|
x << ub.x() - lb.x(), 0, 0, 0;
|
||||||
|
Eigen::Vector4f y;
|
||||||
|
y << 0, ub.y() - lb.y(), 0, 0;
|
||||||
|
Eigen::Vector4f z;
|
||||||
|
z << 0, 0, ub.z() - lb.z(), 0;
|
||||||
positions.push_back(o);
|
positions.push_back(o);
|
||||||
positions.push_back(o + x);
|
positions.push_back(o + x);
|
||||||
positions.push_back(o + x);
|
positions.push_back(o + x);
|
||||||
|
@ -242,7 +249,7 @@ void Viewer::drawContents()
|
||||||
camera().ComputeCameraMatrices(view, proj);
|
camera().ComputeCameraMatrices(view, proj);
|
||||||
Eigen::Matrix4f mvp = proj * view;
|
Eigen::Matrix4f mvp = proj * view;
|
||||||
|
|
||||||
if(chkRenderMesh->checked())
|
if (chkRenderMesh->checked())
|
||||||
renderer.Render(view, proj, shadingBtn->selectedIndex() == 1);
|
renderer.Render(view, proj, shadingBtn->selectedIndex() == 1);
|
||||||
|
|
||||||
ShaderPool::Instance()->simpleShader.bind();
|
ShaderPool::Instance()->simpleShader.bind();
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include "Viewer.h"
|
#include "Viewer.h"
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
std::cout.imbue(std::locale(""));
|
std::cout.imbue(std::locale(""));
|
||||||
|
|
||||||
|
@ -25,11 +25,10 @@ int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
nanogui::mainloop();
|
nanogui::mainloop();
|
||||||
}
|
}
|
||||||
catch (std::runtime_error& e)
|
catch (std::runtime_error &e)
|
||||||
{
|
{
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nanogui::shutdown();
|
nanogui::shutdown();
|
||||||
|
|
Loading…
Reference in a new issue