00001
00002
00003
00004 #ifndef BVERT_H_HAS_BEEN_INCLUDED
00005 #define BVERT_H_HAS_BEEN_INCLUDED
00006
00007 #include "disp/color.H"
00008 #include "mesh/bedge.H"
00009 #include "mesh/bmesh_curvature.H"
00010
00011
00012
00013
00014
00015
00016
00017 class Bvert : public Bsimplex {
00018 public:
00019
00020
00021 enum {
00022 VALID_COLOR_BIT = Bsimplex::NEXT_AVAILABLE_BIT,
00023 VALID_NORMAL_BIT,
00024 VALID_CCW_BIT,
00025 NON_MANIFOLD_BIT,
00026 VALID_NON_MANIFOLD_BIT,
00027 CREASE_BIT,
00028 VALID_CREASE_BIT,
00029 STRESSED_BIT,
00030 VALID_STRESSED_BIT,
00031 NEXT_AVAILABLE_BIT
00032 };
00033
00034
00035 Bvert(CWpt& p=mlib::Wpt::Origin()) : _loc(p), _adj(6), _alpha(1) { }
00036 virtual ~Bvert();
00037
00038
00039
00040 CWpt& loc() const { return _loc; }
00041 Wpt wloc()const;
00042 NDCZpt ndc() const;
00043 PIXEL pix() const { return mlib::PIXEL(wloc());}
00044
00045 int degree() const { return _adj.num(); }
00046 CCOLOR& color() const { return _color; }
00047 double alpha() const { return _alpha; }
00048 bool has_color() const { return is_set(VALID_COLOR_BIT); }
00049
00050
00051 CBedge_list& get_adj() const { return _adj; }
00052
00053
00054
00055 void clear_flag02() {
00056 clear_flag();
00057 _adj.clear_flag02();
00058 }
00059
00060
00061
00062
00063
00064
00065 Wvec compute_normal(const ARRAY<Bface*>& faces) const;
00066
00067
00068
00069 CWvec& norm() const {
00070 if (!is_set(VALID_NORMAL_BIT))
00071 ((Bvert*)this)->set_normal();
00072 return _norm;
00073 }
00074
00075
00076
00077
00078
00079 void set_norm(Wvec n) {
00080 _norm = n.normalized();
00081 set_bit(VALID_NORMAL_BIT);
00082 }
00083
00084
00085 Wvec norm(CSimplexFilter& f) const;
00086
00087
00088
00089 Wvec wnorm() const;
00090
00091
00092
00093 void get_normals(ARRAY<Wvec>& norms) const;
00094
00095
00096
00097
00098 void set_loc(CWpt& p) { _loc = p; geometry_changed(); }
00099 void offset_loc(CWvec& v) { set_loc(_loc + v); }
00100 void transform(CWtransf& xf) { set_loc(xf*_loc); notify_xform(xf); }
00101
00102
00103 void set_color(CCOLOR &c, double a=1) {
00104 _color = c;
00105 _alpha = a;
00106 set_bit(VALID_COLOR_BIT,1);
00107 color_changed();
00108 }
00109
00110
00111 double dist(CBvert* v) { return v ? loc().dist(v->loc()) : 0.0; }
00112
00113
00114 double wdist(CBvert* v) { return v ? wloc().dist(v->wloc()) : 0.0; }
00115
00116
00117
00118
00119 Bedge* e (int k) const { return _adj[k]; }
00120
00121
00122 Bvert* nbr(int k) const {
00123 return _adj.valid_index(k) ? _adj[k]->other_vertex(this) : 0;
00124 }
00125
00126 Bvert* nbr(CBedge* e) const { return e ? e->other_vertex(this) : 0; }
00127
00128
00129
00130
00131 Bvert_list get_nbrs(CBedge_list& edges) const;
00132
00133
00134
00135 Wpt nbr_loc(int k) const { Bvert* n = nbr(k); assert(n); return n->loc(); }
00136 Wpt nbr_loc(CBedge* e) const { Bvert* n = nbr(e); assert(n); return n->loc(); }
00137
00138
00139
00140
00141
00142
00143 void get_faces(ARRAY<Bface*>& ret) const;
00144
00145
00146
00147 Bface_list get_faces() const;
00148
00149
00150
00151 void get_quad_faces(ARRAY<Bface*>& ret) const;
00152
00153
00154
00155 void get_q_faces(ARRAY<Bface*>& ret) const;
00156
00157
00158
00159 void get_all_faces(ARRAY<Bface*>& ret) const;
00160
00161 Bface_list get_all_faces() const;
00162
00163 int num_tris() const;
00164 int num_quads() const;
00165
00166
00167 Bedge* lookup_edge(CBvert* v) const {
00168 if (v == this)
00169 return 0;
00170 for(int k=0; k<_adj.num(); k++)
00171 if(_adj[k]->contains(v))
00172 return _adj[k];
00173 return 0;
00174 }
00175
00176
00177 bool is_adjacent(CBvert* v) const {
00178 for(int k=0; k<_adj.num(); k++)
00179 if(v == _adj[k]->other_vertex(this))
00180 return 1;
00181 return 0;
00182 }
00183
00184
00185 void get_nbrs(ARRAY<Bvert*>& nbrs) const;
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 Bedge_list get_ccw_edges() const;
00196
00197
00198 Bvert_list get_ccw_nbrs() const;
00199
00200
00201
00202
00203 void get_manifold_edges(ARRAY<Bedge*>& ret) const;
00204
00205
00206 Bedge_list get_manifold_edges() const {
00207 Bedge_list ret;
00208 get_manifold_edges(ret);
00209 return ret;
00210 }
00211
00212 Bedge_list strong_edges() const { return get_manifold_edges().strong_edges(); }
00213 double avg_strong_len() const { return strong_edges().avg_len(); }
00214
00215
00216
00217
00218
00219 void get_primary_nbrs(ARRAY<Bvert*>& nbrs) const;
00220
00221
00222
00223
00224 void get_p_nbrs(ARRAY<Bvert*>& nbrs) const;
00225
00226
00227 ARRAY<Bvert*> get_p_nbrs() const {
00228 ARRAY<Bvert*> ret;
00229 get_p_nbrs(ret);
00230 return ret;
00231 }
00232
00233 int p_degree() const {
00234 return is_manifold() ? degree() : get_p_nbrs().num();
00235 }
00236
00237
00238 void get_q_nbrs(ARRAY<Bvert*>& q) const;
00239
00240
00241
00242
00243
00244 Bedge* next_border_edge_cw();
00245
00246
00247 Bvert* next_border_vert_cw() {
00248 Bedge* border = next_border_edge_cw();
00249 return border ? border->other_vertex(this) : 0;
00250 }
00251
00252
00253 void operator +=(Bedge* e);
00254 int operator -=(Bedge* e);
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 bool order_edges_ccw();
00265
00266
00267
00268 double star_sum_angles() const;
00269
00270
00271 double star_area() const;
00272
00273 double min_dot() const {
00274 double ret = 1;
00275 for (int i=0; i < degree(); i++)
00276 ret = min(ret, e(i)->dot());
00277 return ret;
00278 }
00279
00280
00281 double min_edge_len() const { return _adj.min_edge_len(); }
00282
00283
00284 double avg_edge_len() const { return _adj.avg_len(); }
00285
00286
00287
00288
00289 Wpt centroid() const;
00290
00291
00292 Wpt area_centroid() const;
00293
00294
00295
00296 Wpt qr_centroid() const;
00297 Wvec qr_delt() const { return qr_centroid() - loc(); }
00298
00299
00300
00301 BMESHcurvature_data::curv_tensor_t curv_tensor() const;
00302 BMESHcurvature_data::diag_curv_t diag_curv() const;
00303 double k1() const;
00304 double k2() const;
00305 Wvec pdir1() const;
00306 Wvec pdir2() const;
00307 BMESHcurvature_data::dcurv_tensor_t dcurv_tensor() const;
00308
00309
00310
00311
00312
00313 int degree(CSimplexFilter& f) const { return _adj.num_satisfy(f); }
00314
00315 int crease_degree() const { return degree(CreaseEdgeFilter()); }
00316 int border_degree() const { return degree(BorderEdgeFilter()); }
00317 int polyline_degree() const { return degree(PolylineEdgeFilter()); }
00318 int stressed_degree() const { return degree(StressedEdgeFilter()); }
00319 int multi_degree() const { return degree(MultiEdgeFilter()); }
00320
00321
00322
00323 bool is_border() const { return (border_degree() > 0); }
00324 bool is_polyline_end() const { return (polyline_degree() % 2) == 1; }
00325 bool is_crease_end() const { return (crease_degree() % 2) == 1; }
00326
00327 bool is_stressed() const {
00328 if (!is_set(VALID_STRESSED_BIT)) {
00329 ((Bvert*)this)->set_bit(VALID_STRESSED_BIT);
00330 ((Bvert*)this)->set_bit(STRESSED_BIT, stressed_degree() > 0);
00331 }
00332 return is_set(STRESSED_BIT);
00333 }
00334 bool is_crease() const {
00335 if (!is_set(VALID_CREASE_BIT)) {
00336 ((Bvert*)this)->set_bit(VALID_CREASE_BIT,1);
00337 ((Bvert*)this)->set_bit(CREASE_BIT, crease_degree() > 0);
00338 }
00339 return is_set(CREASE_BIT);
00340 }
00341
00342
00343 Wpt eye_local() const;
00344
00345
00346 Wvec eye_vec() const { return (eye_local() - loc()).normalized(); }
00347
00348
00349
00350 double eye_vec_dot_norm() const { return eye_vec() * norm(); }
00351
00352
00353 bool is_front_facing() const { return (eye_local() - loc()) * norm() > 0; }
00354
00355 bool is_sharp_point(double sharpness=M_PI/2);
00356
00357 bool is_non_manifold() const { return multi_degree() > 0; }
00358 bool is_manifold() const { return !is_non_manifold(); }
00359
00360
00361
00362 int face_degree(CSimplexFilter& f) const;
00363
00364
00365 virtual void geometry_changed();
00366 virtual void normal_changed();
00367 virtual void degree_changed();
00368 virtual void star_changed() { clear_bit(VALID_CCW_BIT); }
00369 virtual void crease_changed() { clear_bit(VALID_CREASE_BIT); }
00370 virtual void color_changed() { set_bit(VALID_COLOR_BIT); }
00371
00372
00373 friend ostream &operator <<(ostream &os, CBvert &v) {
00374 return os << v.loc()[0] << " "
00375 << v.loc()[1] << " "
00376 << v.loc()[2] << endl;
00377 }
00378 friend istream &operator >>(istream &is, Bvert &v) {
00379 double x,y,z;
00380 is >> x >> y >> z;
00381 v.set_loc(Wpt(x,y,z));
00382 return is;
00383 }
00384
00385 friend STDdstream &operator <<(STDdstream &d, CBvert &v) {
00386 return d << v.loc()[0] << v.loc()[1] << v.loc()[2];
00387 }
00388 friend STDdstream &operator >>(STDdstream &d, Bvert &v) {
00389 double x,y,z;
00390 d >> x >> y >> z;
00391 v.set_loc(Wpt(x,y,z));
00392 return d;
00393 }
00394
00395
00396
00397 virtual int dim() const { return 0; }
00398
00399
00400 virtual int index() const;
00401
00402
00403
00404
00405
00406
00407 virtual bool view_intersect(
00408 CNDCpt&,
00409 Wpt&,
00410 double&,
00411 double&,
00412 Wvec& n
00413 ) const;
00414
00415 virtual Bface* get_face() const;
00416 virtual bool on_face(CBface* f) const;
00417
00418 virtual void project_barycentric(CWpt&, mlib::Wvec& bc) const {
00419 bc.set(1,0,0);
00420 }
00421 virtual void bc2pos(CWvec&, mlib::Wpt& pos) const { pos = _loc; }
00422
00423 virtual Bsimplex* bc2sim(CWvec&) const { return (Bsimplex*)this; }
00424
00425
00426
00427 virtual Bsimplex_list neighbors() const;
00428
00429
00430 virtual bool local_search(Bsimplex *&end, Wvec &final_bc,
00431 CWpt &target, mlib::Wpt &reached,
00432 Bsimplex *repeater = 0, int iters = 30);
00433 virtual NDCpt nearest_pt_ndc(mlib::CNDCpt& p, mlib::Wvec &bc, int &is_on_simplex) const;
00434 virtual Wpt nearest_pt(mlib::CWpt& p, mlib::Wvec &bc, bool &is_on_simplex) const;
00435
00436
00437
00438
00439 protected:
00440 Wpt _loc;
00441 Bedge_list _adj;
00442 COLOR _color;
00443 double _alpha;
00444 Wvec _norm;
00445
00446
00447
00448
00449 void set_normal();
00450 };
00451
00452 inline Bedge*
00453 lookup_edge(CBvert* a, CBvert* b)
00454 {
00455 return (a && b) ? a->lookup_edge(b) : 0;
00456 }
00457
00458 inline Bvert*
00459 bvert(Bsimplex* sim)
00460 {
00461 return is_vert(sim) ? (Bvert*)sim : 0;
00462 }
00463
00464 inline Wpt
00465 Bedge::interp(double s) const
00466 {
00467
00468
00469
00470 return _v1->loc() + vec()*s;
00471 }
00472
00473
00474
00475
00476 class Bvert_list : public SimplexArray<Bvert_list,Bvert*> {
00477 public:
00478
00479
00480
00481 explicit Bvert_list(int n=0) : SimplexArray<Bvert_list,Bvert*>(n) {}
00482 explicit Bvert_list(Bvert* v) : SimplexArray<Bvert_list,Bvert*>(v) {}
00483 Bvert_list(CARRAY<Bvert*>& list) : SimplexArray<Bvert_list,Bvert*>(list) {}
00484
00485
00486
00487
00488
00489 void clear_flag02() const {
00490 for (int i=0; i<_num; i++)
00491 _array[i]->clear_flag02();
00492 }
00493
00494
00495 Wpt_list pts() const {
00496 Wpt_list ret(_num);
00497 for (int i=0; i<_num; i++)
00498 ret += _array[i]->loc();
00499 ret.update_length();
00500 return ret;
00501 }
00502
00503
00504 Wpt_list wpts() const {
00505 Wpt_list ret(_num);
00506 for (int i=0; i<_num; i++)
00507 ret += _array[i]->wloc();
00508 ret.update_length();
00509 return ret;
00510 }
00511
00512
00513 Wpt center() const { return pts().average(); }
00514
00515
00516 Wpt sum() const { return pts().sum(); }
00517
00518
00519
00520
00521 Bface_list one_ring_faces() const;
00522
00523
00524 Bface_list two_ring_faces() const;
00525
00526
00527
00528 Bedge_list get_outer_edges() const;
00529
00530
00531
00532 Bedge_list get_inner_edges() const;
00533
00534 void transform(CWtransf &xf) {
00535 for (int i=0; i<num(); i++)
00536 (*this)[i]->transform(xf);
00537 }
00538
00539
00540
00541
00542
00543
00544
00545
00546 bool forms_chain() const;
00547 bool forms_closed_chain() const;
00548
00549
00550
00551
00552
00553 Bedge_list get_chain(bool try_close=false) const;
00554
00555
00556
00557 Bedge_list get_closed_chain() const;
00558 };
00559 typedef const Bvert_list CBvert_list;
00560
00561 #endif // BVERT_H_HAS_BEEN_INCLUDED
00562
00563