Moby
Polyhedron.h
1 /****************************************************************************
2  * Copyright 2014 Evan Drumwright
3  * This library is distributed under the terms of the Apache V2.0
4  * License (obtainable from http://www.apache.org/licenses/LICENSE-2.0).
5  ****************************************************************************/
6 
7 #ifndef _POLYHEDRON_H
8 #define _POLYHEDRON_H
9 
10 #include <vector>
11 #include <Moby/Constants.h>
12 #include <Moby/Plane.h>
13 #include <Moby/Log.h>
14 #include <Moby/NumericalException.h>
15 
16 // needed for qhull
17 extern "C"
18 {
19  #include <qhull/qhull_a.h>
20 }
21 
22 
23 namespace Moby {
24 
25 class PolyhedralPrimitive;
26 
28 class Polyhedron
29 {
30  friend class TessellatedPolyhedron;
31 
32  public:
33  class Edge;
34 
36  struct Feature
37  {
38  virtual ~Feature() {}
39  };
40 
42  struct Vertex : public Feature
43  {
44  virtual ~Vertex() {}
45  Ravelin::Origin3d o; // the data
46  std::list<boost::weak_ptr<Edge> > e; // edges coincident to this vertex
47  boost::shared_ptr<void> data; // arbitrary user data
48  };
49 
51  struct Face : public boost::enable_shared_from_this<Face>, public Feature
52  {
53  virtual ~Face() {}
54  std::list<boost::weak_ptr<Edge> > e; // edges coincident to this face (ccw ordering)
55  Plane get_plane() const;
56  boost::shared_ptr<void> data; // arbitrary user data
57  };
58 
60  struct Edge : public boost::enable_shared_from_this<Edge>, public Feature
61  {
62  virtual ~Edge() {}
63  boost::shared_ptr<Vertex> v1, v2; // vertices of this edge
64  boost::shared_ptr<Face> face1, face2; // faces coincident to this edge
65  boost::shared_ptr<void> data; // arbitrary user data
66  };
67 
70  {
71  public:
72  VertexFaceIterator(boost::shared_ptr<Face> f, bool ccw);
73  boost::shared_ptr<Vertex> operator*();
74  void advance();
75  bool has_next();
76 
77  private:
78  boost::shared_ptr<Face> f;
79  boost::shared_ptr<Vertex> v;
80  std::list<boost::weak_ptr<Edge> >::const_reverse_iterator cw_iter;
81  std::list<boost::weak_ptr<Edge> >::const_iterator ccw_iter;
82  bool ccw;
83  };
84 
85  enum LocationType { eInside, eOutside, eOnVertex, eOnEdge, eOnFace };
86 
87  Polyhedron();
88  Polyhedron(const Polyhedron& p) { _convexity_computed = false; operator=(p); }
89  static double vclip(boost::shared_ptr<const PolyhedralPrimitive> pA, boost::shared_ptr<const PolyhedralPrimitive> pB, boost::shared_ptr<const Ravelin::Pose3d> poseA, boost::shared_ptr<const Ravelin::Pose3d> poseB, boost::shared_ptr<const Polyhedron::Feature>& closestA, boost::shared_ptr<const Polyhedron::Feature>& closestB);
90  static Polyhedron calc_minkowski_diff(boost::shared_ptr<const PolyhedralPrimitive> pA, boost::shared_ptr<const PolyhedralPrimitive> pB, boost::shared_ptr<const Ravelin::Pose3d> poseA, boost::shared_ptr<const Ravelin::Pose3d> poseB);
91 /*
92  double find_closest_features(const Ravelin::Origin3d& p, std::list<boost::shared_ptr<Feature> >& closest_features, bool& inside) const;
93 */
94  boost::shared_ptr<Polyhedron::Feature> find_closest_feature(const Ravelin::Origin3d& p, unsigned closest_facet) const;
95  Polyhedron& operator=(const Polyhedron& p);
96  Polyhedron shallow_copy() const;
97  std::vector<boost::shared_ptr<Vertex> >& get_vertices() { return _vertices; }
98  const std::vector<boost::shared_ptr<Vertex> >& get_vertices() const { return _vertices; }
99  const std::vector<boost::shared_ptr<Edge> >& get_edges() const { return _edges; }
100  const std::vector<boost::shared_ptr<Face> >& get_faces() const { return _faces; }
101  bool inside(const Ravelin::Origin3d& point, double tol = NEAR_ZERO);
102  bool inside_or_on(const Ravelin::Origin3d& point, double tol = NEAR_ZERO);
103  LocationType location(const Ravelin::Origin3d& point, boost::shared_ptr<Polyhedron::Feature>& closest_feature, double tol = NEAR_ZERO) const;
104  static void to_vrml(std::ostream& out, const Polyhedron& p, Ravelin::Origin3d diffuse_color = Ravelin::Origin3d(1,1,1), bool wireframe = false);
105  double calc_volume() const;
106  bool degenerate() const;
107  void write_to_obj(const std::string& filename) const;
108  Polyhedron transform(const Ravelin::Transform3d& T) const;
109 
110  template <class ForwardIterator>
111  static Polyhedron calc_convex_hull(ForwardIterator begin, ForwardIterator end);
112 
114  double calc_signed_distance(const Ravelin::Origin3d& point, unsigned& closest_facet) const;
115 
117  double calc_signed_distance(const Ravelin::Origin3d& point) const { unsigned discard; return calc_signed_distance(point, discard); }
118 
120  std::pair<Ravelin::Origin3d, Ravelin::Origin3d> get_bounding_box_corners() const { return std::make_pair(_bb_min, _bb_max); }
121 
123  bool is_convex() { return convexity() < std::sqrt(NEAR_ZERO); }
124 
126 
131  double convexity() { if (!_convexity_computed) determine_convexity(); return _convexity; }
132 
134 
140  enum FeatureType { eVertex, eEdge, eFace };
141  static double calc_dist(FeatureType fA, FeatureType fB, boost::shared_ptr<const Polyhedron::Feature> closestA, boost::shared_ptr<const Polyhedron::Feature> closestB, Ravelin::Transform3d& aTb);
142  private:
143  static boost::shared_ptr<Plane> voronoi_plane (FeatureType fA, FeatureType fB, boost::shared_ptr<const Ravelin::Pose3d> pose, boost::shared_ptr<const Polyhedron::Feature>& featureA, boost::shared_ptr<const Polyhedron::Feature>& featureB);
144  static bool clip_edge(boost::shared_ptr<const Polyhedron::Edge> edge, Ravelin::Transform3d fTe, double& min_lambda, double& max_lambda, boost::shared_ptr<const Polyhedron::Feature >& min_N, boost::shared_ptr<const Polyhedron::Feature >& max_N, const std::list<std::pair<boost::shared_ptr<const Polyhedron::Feature>, boost::shared_ptr<Plane> > >& planes_neighbors);
145  static bool post_clip_deriv_check(FeatureType& fX, boost::shared_ptr<const Polyhedron::Feature >& X , boost::shared_ptr<const Polyhedron::Edge> edge, Ravelin::Transform3d& xTe, double& min_lambda, double& max_lambda, boost::shared_ptr<const Polyhedron::Feature >& min_N, boost::shared_ptr<const Polyhedron::Feature >& max_N);
146  static bool is_one_face_penetration(boost::shared_ptr<const Polyhedron::Feature>& fFace, boost::shared_ptr<const PolyhedralPrimitive> pE, boost::shared_ptr<const Polyhedron::Feature>& fEdge, Ravelin::Transform3d& fTe);
147  static void find_deepest_feature(boost::shared_ptr<const Polyhedron::Feature>& face, boost::shared_ptr<const Polyhedron::Feature>& edge, Moby::Polyhedron::FeatureType& fE, Ravelin::Transform3d& fTe);
148  static double minkowski_optimum_distance(boost::shared_ptr<const PolyhedralPrimitive> pA, boost::shared_ptr<const PolyhedralPrimitive> pB, Ravelin::Transform3d& aTb);
149 
150  //void promote_featrues(FeatureType& fA, FeatureType& fB, boost::shared_ptr<const Polyhedron::Feature>& closestA, boost::shared_ptr<const Polyhedron::Feature>& closestB, Ravelin::Transform3d& aTb)
151 
152  enum UpdateRule { eDone, eContinue, eInterpenetrating };
153 
154  static UpdateRule handle_local_minimum(boost::shared_ptr<const Polyhedron::Vertex>& V, FeatureType& fF, boost::shared_ptr<const Polyhedron::Feature>& face, const Polyhedron& face_poly, const Ravelin::Transform3d& vTf);
155 
156  static UpdateRule update_vertex_vertex(FeatureType& fA, FeatureType& fB, Ravelin::Transform3d& aTb, boost::shared_ptr<const Polyhedron::Feature>& closestA, boost::shared_ptr<const Polyhedron::Feature>& closestB);
157  static UpdateRule update_vertex_edge(FeatureType& fA, FeatureType& fB, Ravelin::Transform3d& aTb, boost::shared_ptr<const Polyhedron::Feature>& closestA, boost::shared_ptr<const Polyhedron::Feature>& closestB);
158  static UpdateRule update_vertex_face(FeatureType& fA, FeatureType& fB, Ravelin::Transform3d& aTb, boost::shared_ptr<const Polyhedron::Feature>& closestA, boost::shared_ptr<const Polyhedron::Feature>& closestB, const Polyhedron& face_poly);
159  static UpdateRule update_edge_edge(FeatureType& fA, FeatureType& fB, Ravelin::Transform3d& aTb, boost::shared_ptr<const Polyhedron::Feature>& closestA, boost::shared_ptr<const Polyhedron::Feature>& closestB);
160  static UpdateRule update_edge_face(FeatureType& fA, FeatureType& fB, Ravelin::Transform3d& aTb, boost::shared_ptr<const Polyhedron::Feature>& closestA, boost::shared_ptr<const Polyhedron::Feature>& closestB);
161  static double sqr(double x) { return x*x; }
162  void calc_bounding_box();
163  static void calc_subexpressions(double w0, double w1, double w2, double& f1, double& f2, double& f3, double& g0, double& g1, double& g2);
164  void determine_convexity();
165 
166  Ravelin::Origin3d _bb_min, _bb_max;
167  double _convexity;
168  bool _convexity_computed;
169 
170  std::vector<boost::shared_ptr<Vertex> > _vertices;
171  std::vector<boost::shared_ptr<Face> > _faces;
172  std::vector<boost::shared_ptr<Edge> > _edges;
173 };
174 
175 std::ostream& operator<<(std::ostream& out, const Polyhedron& m);
176 std::ostream& operator<<(std::ostream& out, const Polyhedron::Vertex& m);
177 std::ostream& operator<<(std::ostream& out, const Polyhedron::Edge& m);
178 std::ostream& operator<<(std::ostream& out, const Polyhedron::Face& m);
179 
180 #include "Polyhedron.inl"
181 
182 } // end namespace
183 
184 #endif
bool is_convex()
Determines whether this polyhedron convex (to w/in floating point tolerance)
Definition: Polyhedron.h:123
The vertex structure.
Definition: Polyhedron.h:42
Defines a plane using the equation <n, x> = d.
Definition: Plane.h:17
Polyhedron()
Creates a minimum polyhedron.
Definition: Polyhedron.cpp:145
The face structure.
Definition: Polyhedron.h:51
void write_to_obj(const std::string &filename) const
Writes the polyhedron to Wavefront OBJ format.
Definition: Polyhedron.cpp:247
void advance()
Advances the iterator clockwise.
Definition: Polyhedron.cpp:1154
static void to_vrml(std::ostream &out, const Polyhedron &p, Ravelin::Origin3d diffuse_color=Ravelin::Origin3d(1, 1, 1), bool wireframe=false)
Finds the feature(s) of this polyhedron closest to the point.
Definition: Polyhedron.cpp:927
double calc_signed_distance(const Ravelin::Origin3d &point) const
Gets the signed distance from a point to the polyhedron.
Definition: Polyhedron.h:117
boost::shared_ptr< Polyhedron::Feature > find_closest_feature(const Ravelin::Origin3d &p, unsigned closest_facet) const
Finds the closest feature of the polyhedron to the point, given the closest facet.
Definition: Polyhedron.cpp:1861
A potentially-non-convex polyhedron of genus 0.
Definition: Polyhedron.h:28
static Polyhedron calc_convex_hull(ForwardIterator begin, ForwardIterator end)
Computes the convex hull for a polyhedron.
Definition: Polyhedron.h:55
double convexity()
Gets the convexity of this polyhedron.
Definition: Polyhedron.h:131
bool has_next()
Checks to see whether the iterator can be advanced clockwise.
Definition: Polyhedron.cpp:1218
iterates over the vertices in a face
Definition: Polyhedron.h:69
Polyhedron & operator=(const Polyhedron &p)
Assignment operator.
Definition: Polyhedron.cpp:152
Plane get_plane() const
Gets the plane containing a face.
Definition: Polyhedron.cpp:97
double calc_signed_distance(const Ravelin::Origin3d &point, unsigned &closest_facet) const
Gets the signed distance and closest facet to a point.
static double calc_dist(FeatureType fA, FeatureType fB, boost::shared_ptr< const Polyhedron::Feature > closestA, boost::shared_ptr< const Polyhedron::Feature > closestB, Ravelin::Transform3d &aTb)
Computes the distance between two features.
Definition: Polyhedron.cpp:1867
boost::shared_ptr< Vertex > operator*()
Dereferences the iterator.
Definition: Polyhedron.cpp:1148
FeatureType
Gets the Voronoi plane from two input features.
Definition: Polyhedron.h:140
A vertex, face, or edge in a polyhedron.
Definition: Polyhedron.h:36
Represents a three-dimensional polyhedron.
Definition: TessellatedPolyhedron.h:28
Polyhedron transform(const Ravelin::Transform3d &T) const
Transforms a polyhedron.
Definition: Polyhedron.cpp:231
static double vclip(boost::shared_ptr< const PolyhedralPrimitive > pA, boost::shared_ptr< const PolyhedralPrimitive > pB, boost::shared_ptr< const Ravelin::Pose3d > poseA, boost::shared_ptr< const Ravelin::Pose3d > poseB, boost::shared_ptr< const Polyhedron::Feature > &closestA, boost::shared_ptr< const Polyhedron::Feature > &closestB)
Executes the V-Clip algorithm on two polyhedra, determining closest features and signed distance...
Definition: Polyhedron.cpp:1238
VertexFaceIterator(boost::shared_ptr< Face > f, bool ccw)
Constructs a vertex-face iterator.
Definition: Polyhedron.cpp:1098
std::pair< Ravelin::Origin3d, Ravelin::Origin3d > get_bounding_box_corners() const
Gets the corners of the axis-aligned bounding box of this polyhedron.
Definition: Polyhedron.h:120
static Polyhedron calc_minkowski_diff(boost::shared_ptr< const PolyhedralPrimitive > pA, boost::shared_ptr< const PolyhedralPrimitive > pB, boost::shared_ptr< const Ravelin::Pose3d > poseA, boost::shared_ptr< const Ravelin::Pose3d > poseB)
Computes the Minkowski difference of two polyhedral primitives.
Definition: Polyhedron.cpp:259
The edge structure.
Definition: Polyhedron.h:60
Polyhedron shallow_copy() const
Does a shallow copy of this polyhedron.
Definition: Polyhedron.cpp:216