00001 #ifndef RefineVertex_HEADER
00002 #define RefineVertex_HEADER
00003
00004 #ifdef HAVE_CONFIG_H
00005 # include <config.h>
00006 #endif
00007
00008 #include "MeshTypes.h"
00009 #include <boost/array.hpp>
00010 #include <geometry/Point.h>
00011 #include <refine-common/ConcentricShells.h>
00012 #include <utilities/FastHash.h>
00013 #include <utilities/OrderedHash.h>
00014 #include <utilities/foreach.h>
00015 #include <vector>
00016
00017 #if 0
00018 #define dprintf(...) printf(__VA_ARGS__);
00019 #define dputs(str) puts(str);
00020 #else
00021 #define dprintf(...)
00022 #define dputs(str)
00023 #endif
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 template <size_t ambient>
00037 class RefineVertex : public boost::noncopyable {
00038 public:
00039 typedef Geometry::Point<ambient> Point;
00040 typedef ::GenericMesh<ambient> Mesh;
00041 typedef ::ConcentricShells<RefineVertex, Point> ConcentricShells;
00042 typedef typename MeshTypes<ambient>::Ball Ball;
00043
00044 private:
00045 const Point p_;
00046 boost::array<std::vector<const Mesh*>, ambient> uppers_;
00047 typedef hudson::FastHashMap<const Mesh*, ConcentricShells, hudson::HashPointer<const Mesh> >
00048 Shells;
00049 Shells shells_;
00050 ConcentricShells topShell_;
00051 int id_;
00052 int cd_;
00053
00054 Ball *handle_;
00055
00056 public:
00057
00058 typedef hudson::FastHashSet<RefineVertex*, hudson::HashPointer<RefineVertex> > VertexSet;
00059 typedef hudson::OrderedHashSet<RefineVertex*, hudson::HashPointer<RefineVertex> > VertexUniqueList;
00060
00065 RefineVertex(const Point& p, unsigned cd = -1): p_(p), id_(-1), cd_(cd), handle_(0) {
00066 }
00067
00072 void setContainingDimension(unsigned cd) {
00073 assert(cd_ == -1);
00074 assert(int(cd) >= 0);
00075 cd_ = cd;
00076 }
00077
00081 void replaceHandle(Ball *handle) {
00082 assert(handle->topological() == ambient);
00083 handle_ = handle;
00084 }
00085
00089 Ball *getHandle() const {
00090 return handle_;
00091 }
00092
00096 void addUpperMesh(const Mesh *m) {
00097 assert(m);
00098 assert(m->topological() != ambient);
00099 assert(cd_ <= int(m->topological()));
00100 std::vector<const Mesh*>& ups = uppers_[m->topological()];
00101
00102
00103 typename std::vector<const Mesh*>::iterator it = std::find(ups.begin(), ups.end(), m);
00104
00105 if (it != ups.end()) {
00106
00107 return;
00108 }
00109
00110
00111
00112
00113 dprintf(" %s adding upper %u-mesh %p\n", toString().c_str(), m->topological(), m);
00114 ups.push_back(m);
00115 std::sort(ups.begin(), ups.end());
00116
00117
00118
00119 BOUNDED_FOREACH(const Mesh *upper, m->begin_uppers(), m->end_uppers()) {
00120 addUpperMesh(upper);
00121 }
00122
00123
00124 shells_.insert(m);
00125 }
00126
00130 void setID(unsigned id) {
00131 assert(id_ == -1);
00132 assert(int(id) >= 0);
00133 dprintf(" vertex %s is now v%u\n", toString().c_str(), id);
00134 id_ = id;
00135 }
00136
00138 typedef typename std::vector<const Mesh*>::const_iterator upper_iterator;
00139 upper_iterator begin_uppers(unsigned d) const { return uppers_[d].begin(); }
00140 upper_iterator end_uppers(unsigned d) const { return uppers_[d].end(); }
00141 const std::vector<const Mesh*>& get_uppers(unsigned d) const { return uppers_[d]; }
00142 bool hasUpperMesh(const Mesh *m) const {
00143 if (m->topological() == ambient) {
00144 return true;
00145 } else {
00146 return shells_.find(m) != shells_.end();
00147 }
00148 }
00149
00151 unsigned getID() const { assert(id_ != -1); return id_; }
00152
00153 unsigned getCD() const { assert(cd_ != -1); return cd_; }
00154
00156 double dist2(const RefineVertex *other) const {
00157 return toPoint().dist2(other->toPoint());
00158 }
00159
00161 struct IsCloser {
00162 const RefineVertex *v_;
00163 IsCloser(const RefineVertex *v): v_(v) { }
00164 bool operator() (const RefineVertex *a, const RefineVertex *b) const {
00165 return a->dist2(v_) < b->dist2(v_);
00166 }
00167 };
00168
00169
00170
00171
00172
00173
00174
00175 private:
00176 ConcentricShells& getShell(const Mesh *m) {
00177 if (m->topological() == ambient) { return topShell_; }
00178 else { return shells_.findOrDie(m); }
00179 }
00180 const ConcentricShells& getShell(const Mesh *m) const {
00181 if (m->topological() == ambient) { return topShell_; }
00182 else { return shells_.findOrDie(m); }
00183 }
00184
00185 public:
00187 bool isCrowded(const Mesh *m) const {
00188 return ! getShell(m).empty();
00189 }
00190 bool isCrowded() const {
00191 return ! topShell_.empty();
00192 }
00193
00195 RefineVertex *getFarVertex(const Mesh *m) const {
00196 return getShell(m).getFarItem();
00197 }
00198 RefineVertex *getFarVertex() const {
00199 return topShell_.getFarItem();
00200 }
00201
00203 void reassignTo(const Mesh *m, RefineVertex *other) {
00204 getShell(m).reassignTo(toPoint(), other->getShell(m), other->toPoint());
00205 }
00206
00208 void addUninserted(const Mesh *m, RefineVertex *uninserted) {
00209 getShell(m).add(toPoint(), uninserted);
00210 }
00211
00214 pair<RefineVertex*, double> findClosest(const Mesh *m, const Point& q, double r2) const {
00215 return getShell(m).findClosest(toPoint(), q, r2);
00216 }
00217
00219
00220
00222 const Point& toPoint() const { return p_; }
00223
00225 double x(size_t i) const { return p_[i]; }
00226
00228 const double *x() const { return p_.data(); }
00229
00231 std::string toString() const {
00232 char buffer[4096];
00233 if (id_ == -1) {
00234 snprintf(buffer, sizeof(buffer), "v[%u] at %s", cd_, p_.toString().c_str());
00235 } else {
00236 snprintf(buffer, sizeof(buffer), "v%u[%u]", getID(), cd_);
00237 }
00238 return buffer;
00239 }
00240
00242 struct Printer {
00243 std::string operator()(const RefineVertex *v) const {
00244 return v->toString();
00245 }
00246 };
00247 };
00248
00249
00250
00251 #undef dprintf
00252 #undef dputs
00253
00254 #endif