00001
00002
00003
00004 #ifndef BSIMPLEX_H_IS_INCLUDED
00005 #define BSIMPLEX_H_IS_INCLUDED
00006
00007 #include "simplex_data.H"
00008
00009 class Bsimplex;
00010 class Bvert;
00011 class Bedge;
00012 class Bface;
00013
00014 typedef const Bsimplex CBsimplex;
00015 typedef const Bvert CBvert;
00016 typedef const Bedge CBedge;
00017 typedef const Bface CBface;
00018
00019 class BMESH;
00020 class Bsimplex_list;
00021
00022
00023
00024
00025
00026
00027
00028 class SimplexFilter {
00029 public:
00030
00031 SimplexFilter() {}
00032 virtual ~SimplexFilter() {}
00033
00034
00035 virtual bool accept(CBsimplex* s) const { return s != 0; }
00036 };
00037 typedef const SimplexFilter CSimplexFilter;
00038
00039
00040
00041
00042
00043
00044 class Bsimplex;
00045 typedef const Bsimplex CBsimplex;
00046 class Bsimplex {
00047 public:
00048
00049
00050
00051
00052
00053
00054 enum {
00055 FLAG_BITS = 2,
00056 SELECTED_BIT,
00057 NEXT_AVAILABLE_BIT
00058 };
00059
00060
00061
00062 Bsimplex() : _key(0), _flag(0), _mesh(0), _data_list(0) {}
00063 virtual ~Bsimplex();
00064
00065
00066
00067 void set_mesh(BMESH* mesh) { _mesh = mesh; }
00068 BMESH* mesh() const { return _mesh; }
00069
00070
00071
00072 uint key() const { return _key ? _key : ((Bsimplex*)this)->generate_key();}
00073 static Bsimplex* lookup(uint k) {
00074 return (k<(uint)_table.num()) ? _table[k] : 0;
00075 }
00076
00077
00078
00079
00080
00081 virtual int dim() const = 0;
00082
00083
00084
00085
00086 virtual int index() const = 0;
00087
00088
00089
00090
00091 uint flag() const { return _flag & FLAG_MASK; }
00092 void clear_flag() { _flag &= ~FLAG_MASK; }
00093 void set_flag(uchar b=1) { clear_flag(); _flag |= b; }
00094
00095
00096 void inc_flag(uint i) {
00097 set_flag(uchar((flag() + i) % (1 << FLAG_BITS)));
00098 }
00099
00100 bool is_set(uint b) const { return (_flag & mask(b)) ? 1 : 0; }
00101 bool is_clear(uint b) const { return !is_set(b); }
00102
00103 void clear_bit(uint b) { _flag &= ~mask(b); }
00104 void set_bit(uint b, int x=1) {
00105 clear_bit(b); if(x) _flag |= mask(b);
00106 }
00107
00108
00109
00110
00111
00112
00113
00114 bool is_selected() const { return is_set(SELECTED_BIT); }
00115
00116
00117
00118 SimplexData* find_data(uint key) const {
00119 return _data_list ? _data_list->get_item(key) : 0;
00120 }
00121
00122 SimplexData* find_data(Cstr_ptr& s) const { return find_data((uint)**s);}
00123 SimplexData* find_data(void *key) const { return find_data((uint)key);}
00124
00125 void add_simplex_data(SimplexData* sd);
00126 void rem_simplex_data(SimplexData* sd) {
00127 if (_data_list)
00128 _data_list->rem(sd);
00129 }
00130
00131
00132 const SimplexDataList* data_list() const { return _data_list; }
00133
00134
00135
00136 virtual void notify_split(Bsimplex *new_simp);
00137 virtual void notify_xform(CWtransf& xf);
00138 virtual void geometry_changed();
00139 virtual void normal_changed();
00140
00141
00142
00143 virtual void project_barycentric(CWpt &loc, mlib::Wvec &bc) const = 0;
00144 virtual void bc2pos(CWvec& bc, mlib::Wpt& pos) const = 0;
00145
00146 Wpt bc2pos(mlib::CWvec& bc) const {
00147 Wpt ret;
00148 bc2pos(bc, ret);
00149 return ret;
00150 }
00151
00152 Wpt& project_to_simplex(mlib::CWpt &pos, mlib::Wpt &ret) {
00153 Wvec bc;
00154 project_barycentric(pos, bc);
00155 clamp_barycentric(bc);
00156 bc2pos(bc, ret);
00157 return ret;
00158 }
00159
00160 virtual Bsimplex* bc2sim(CWvec& bc) const = 0;
00161
00162 static void clamp_barycentric(Wvec &bc) {
00163 bc.set(max(bc[0],0.0), max(bc[1],0.0), max(bc[2],0.0));
00164 bc /= (bc[0] + bc[1] + bc[2]);
00165 }
00166
00167
00168
00169
00170
00171
00172
00173 virtual bool view_intersect(
00174 CNDCpt&,
00175 Wpt&,
00176 double&,
00177 double&,
00178 Wvec& n
00179 ) const = 0;
00180
00181
00182 virtual bool near_point(CNDCpt& p, mlib::Wpt& hit) const {
00183 double d, d2d; Wvec n;
00184 return view_intersect(p, hit, d, d2d, n);
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 Bsimplex* walk_to_target(
00197 CWpt& target, CSimplexFilter& filter = SimplexFilter()
00198 ) const;
00199 Bsimplex* walk_to_target(
00200 CWpt& target,
00201 Wpt& near_pt,
00202 Wvec& near_bc,
00203 CSimplexFilter& filter = SimplexFilter()
00204 ) const {
00205 Bsimplex* ret = walk_to_target(target, filter);
00206 assert(ret);
00207 near_pt = ret->nearest_pt(target, near_bc);
00208 return ret;
00209 }
00210
00211
00212 virtual Bsimplex_list neighbors() const = 0;
00213
00214
00215 double dist(CWpt& p) const { return nearest_pt(p ).dist(p); }
00216 double dist(CWpt& p, mlib::Wvec& bc) const { return nearest_pt(p,bc).dist(p); }
00217
00218
00219
00220 virtual bool local_search(
00221 Bsimplex *&end, Wvec &final_bc,
00222 CWpt &target, mlib::Wpt &reached,
00223 Bsimplex *repeater = 0, int iters = 30
00224 ) = 0;
00225
00226 virtual NDCpt nearest_pt_ndc(mlib::CNDCpt&, mlib::Wvec&, int&) const = 0;
00227 virtual Wpt nearest_pt(mlib::CWpt& p, mlib::Wvec &bc, bool &is_on_simplex) const = 0;
00228 virtual Wpt nearest_pt(mlib::CWpt& p, mlib::Wvec& bc) const {
00229 bool b;
00230 return nearest_pt(p,bc,b);
00231 }
00232 virtual Wpt nearest_pt(mlib::CWpt& p) const {
00233 Wvec bc;
00234 return nearest_pt(p,bc);
00235 }
00236
00237
00238 virtual bool on_face(const Bface* f) const = 0;
00239 virtual Bface* get_face() const = 0;
00240
00241
00242
00243
00244 protected:
00245 uint _key;
00246 uint _flag;
00247 BMESH* _mesh;
00248 SimplexDataList* _data_list;
00249
00250
00251
00252
00253 uint generate_key();
00254
00255
00256
00257 public:
00258 class IDtable : public ARRAY<Bsimplex*> {
00259 public:
00260 IDtable(int max) : ARRAY<Bsimplex*>(max) { *this += (Bsimplex*)0; }
00261 };
00262 protected:
00263 static IDtable _table;
00264
00265 enum { FLAG_MASK = ((1 << FLAG_BITS) - 1) };
00266
00267
00268 static uint mask(uint b) { return (1 << (b - 1)); }
00269 };
00270
00271 inline bool
00272 is_vert(CBsimplex* s)
00273 {
00274 return (s && (s->dim() == 0));
00275 }
00276
00277 inline bool
00278 is_edge(CBsimplex* s)
00279 {
00280 return (s && (s->dim() == 1));
00281 }
00282
00283 inline bool
00284 is_face(CBsimplex* s)
00285 {
00286 return (s && (s->dim() == 2));
00287 }
00288
00289 inline BMESH*
00290 get_mesh(CBsimplex* s)
00291 {
00292 return s ? s->mesh() : (BMESH*)0;
00293 }
00294
00295 inline Bface*
00296 get_bface(CBsimplex* s)
00297 {
00298 return s ? s->get_face() : (Bface*)0;
00299 }
00300
00301 #endif // BSIMPLEX_H_IS_INCLUDED
00302
00303