ProtectedBall.h

Go to the documentation of this file.
00001 #ifndef ProtectedBall_HEADER
00002 #define ProtectedBall_HEADER
00003 
00004 #include <geometry/Circles.h>
00005 #include <utilities/hash.h>
00006 #include "RefineVertex.h"
00007 #include "SplitData.h"
00008 #include <string>
00009 #include "GenericMesh.h"
00010 #include "MeshTypes.h"
00011 using namespace std;
00012 
00013 /* signature BALL =
00014    sig
00015      type ball
00016      type point
00017      val center : ball -> (point * real)
00018      val split : ball -> unit
00019      val encroached : ball * point -> bool
00020    end
00021    */
00022 
00023 /***************************************************************************
00024  * Wrap a simplex in arbitrary dimension and protect it against encroachment.
00025  *
00026  * This is the object used in SVR to communicate between dimensions.
00027  * A simplex s in dimension i stores pointers to all lower-dimensional
00028  * protected balls b that s intersects (if b is on a sub-feature of the feature
00029  * that s is on).  The reverse pointer is also kept by the simplex that b
00030  * protects (furthermore, s points to higher-dimensional protected balls).
00031  *
00032  * The work queue and the main loop use the protected balls to avoid needing to
00033  * think hard about dimension.  This simplifies the code, though type safety
00034  * (and thus runtime, since we'd eliminate runtime checks) would be improved
00035  * by using appropriate-dimension simplices instead.  The old SML code did that
00036  * and was largely illegible, so the current approach is prefered.
00037  ***************************************************************************/
00038 template <size_t amb>
00039 struct ProtectedBall {
00040   typedef Geometry::CenterRadius<amb> CenterRadius;
00041   typedef ::SplitData<amb> SplitData;
00042   typedef typename MeshTypes<amb>::BallSet BallSet;
00043   typedef typename MeshTypes<amb>::Vertex Vertex;
00044   typedef typename MeshTypes<amb>::GenericMesh GenericMesh;
00045 
00046   virtual ~ProtectedBall() { }
00047 
00048   virtual size_t topological() const = 0;
00049   static size_t ambient() { return amb; }
00050   virtual const GenericMesh *getMesh() const = 0;
00051   virtual void gatherVertices(typename Vertex::VertexUniqueList&) const = 0;
00052   virtual bool has(const Vertex*) const = 0;
00053 
00054   // Functions that query mesh state and could be specific-dimensional.
00055 
00056   virtual bool isLive() const = 0; //<! Is this ball still to be protected?
00057   virtual CenterRadius center() const = 0; //<! Center/radius of the ball
00058   virtual double radiusEdge2() const = 0; //<! Geometry of the underlying simplex.
00059   virtual double computeSigma() const = 0; //<! Aspect ratio (as volume / e^3).
00060 
00061   // Functions that query cross-dimensional state.
00062 
00063   virtual bool isResolved() const = 0; //<! Is this ball resolved in the top mesh?
00064   virtual bool encroachedBy(const Vertex*) const = 0; //<! True if the vertex lies in the open ball (this is implemented as an approximate test)
00065   virtual bool inSphereExact(const Vertex*) const = 0; //<! True if the vertex lies in the open ball (robust test; v must be on the plane of b)
00066   virtual void gatherUppers(BallSet&) const = 0; //<! Gather all up-pointers: pointers to higher-dimensional balls that point to this ball.
00067   virtual void gatherLowers(BallSet&) const = 0; //<! Gather all down-pointers: all balls that lie on a sub-feature of this ball's feature, and that intersect this ball.
00068 
00069 
00078   virtual bool split(SplitData&, Vertex *hint=0, bool force=false) = 0;
00079 
00080   // Functions that update cross-dimensional state.
00081 
00082   virtual void blindlyAddUpper(ProtectedBall *up) = 0; //<! Add an up-pointer.
00083   virtual void blindlyAddLower(ProtectedBall *lower) = 0; //<! Add a down-pointer.
00084   virtual void removeUpper(ProtectedBall *up) = 0; //<! Remove an up-pointer.
00085   virtual void removeLower(ProtectedBall *lower) = 0; //<! Remove a down-pointer.
00086 
00087   virtual void checkAddLower(ProtectedBall *lower) = 0; //<! Add a down-pointer if the balls intersect.  We also set lower's up-pointer.
00088 
00089   virtual std::string toString() const = 0;
00090 
00091 
00094   bool approximatelyIntersects(const CenterRadius& other) const {
00095     return center().approximatelyIntersects(other);
00096   }
00097 
00100   bool approximatelyIntersects(ProtectedBall *other) const {
00101     return approximatelyIntersects(other->center());
00102   }
00103 };
00104 
00111 template <class Mesh>
00112 struct PBall : public ProtectedBall<Mesh::ambient_dimension> {
00113   static const int ambient = Mesh::ambient_dimension;
00114   typedef ProtectedBall<ambient> super;
00115   typedef ProtectedBall<ambient> Ball;
00116   typedef typename super::CenterRadius CenterRadius;
00117   typedef typename super::Vertex Vertex;
00118   typedef ::SplitData<ambient> SplitData;
00119 
00120   /*
00121   static const size_t ambient = Mesh::ambient_dimension;
00122   static const size_t topological = Mesh::topological_dimension;
00123   */
00124 
00125   typedef typename Mesh::Simplex Simplex;
00126 
00127   PBall(Mesh *mesh, const Simplex& s): s_(s), mesh_(mesh) {
00128     mesh->setBall(s_, this);
00129   }
00130 
00132   const Simplex& toSimplex() const { return s_; }
00133 
00135   virtual size_t topological() const { return Mesh::topological_dimension; }
00136 
00138   virtual GenericMesh<ambient> *getMesh() const { return mesh_; }
00139 
00140   virtual void gatherVertices(typename Vertex::VertexUniqueList& vset) const {
00141     BOOST_FOREACH(Vertex *v, s_) {
00142       vset.insert(v);
00143     }
00144   }
00145   virtual bool has(const Vertex* v) const {
00146     return s_.has(v);
00147   }
00148 
00150   virtual bool isLive() const {
00151     return mesh_->isMember(s_);
00152   }
00153 
00155   virtual CenterRadius center() const {
00156     return mesh_->circumcenter(s_);
00157   }
00158 
00160   virtual double radiusEdge2() const {
00161     return mesh_->radiusEdge2(s_);
00162   }
00163   virtual double computeSigma() const {
00164     return mesh_->computeSigma(s_);
00165   }
00166 
00167 
00169   virtual bool encroachedBy(const Vertex *v) const {
00170     return mesh_->encroachedBy(s_, v);
00171   }
00172 
00173   virtual bool inSphereExact(const Vertex *v) const {
00174     return mesh_->inSphereExact(s_, v);
00175   }
00176 
00178   virtual bool isResolved() const {
00179     return mesh_->isResolved(s_);
00180   }
00181 
00183   virtual void gatherUppers(typename super::BallSet& set) const {
00184     mesh_->gatherUppers(s_, set);
00185   }
00186 
00188   virtual void gatherLowers(typename super::BallSet& set) const {
00189     mesh_->gatherLowers(s_, set);
00190   }
00191 
00192 
00194   virtual bool split(SplitData& sdata, Vertex *inserthint, bool force) {
00195     return mesh_->split(s_, sdata, inserthint, force);
00196   }
00197 
00199   virtual void blindlyAddUpper(Ball *up) {
00200     mesh_->blindlyAddUpper(s_, up);
00201   }
00202 
00204   virtual void blindlyAddLower(Ball *lower) {
00205     mesh_->blindlyAddLower(s_, lower);
00206   }
00207 
00209   virtual void removeUpper(Ball *up) {
00210     mesh_->removeUpper(s_, up);
00211   }
00212 
00214   virtual void removeLower(Ball *lower) {
00215     mesh_->removeLower(s_, lower);
00216   }
00217 
00219   virtual void checkAddLower(Ball *lower) {
00220     mesh_->checkAddLower(s_, lower);
00221   }
00222 
00223   virtual std::string toString() const {
00224     char buffer[4096];
00225     string s = s_.toString();
00226     snprintf(buffer, sizeof(buffer), "%u-mesh[%p]:%s", unsigned(Mesh::topological_dimension), mesh_, s.c_str());
00227     return buffer;
00228   }
00229 
00230   private:
00231   Simplex s_;
00232   Mesh *mesh_;
00233 };
00234 
00237 template <class Mesh>
00238 ProtectedBall<Mesh::ambient_dimension> *makeProtectedBall(
00239     Mesh *m,
00240     const typename Mesh::Simplex& s) {
00241   return new PBall<Mesh>(m, s);
00242 }
00243 
00244 #endif

Generated on Thu Mar 27 19:04:14 2008 by  doxygen 1.4.6