00001 #ifndef LMESH_H_HAS_BEEN_INCLUDED
00002 #define LMESH_H_HAS_BEEN_INCLUDED
00003
00004 #include "lstrip.H"
00005 #include "ledge_strip.H"
00006 #include "lvert_strip.H"
00007 #include "subdiv_calc.H"
00008
00009 #define CLMESHptr const LMESHptr
00010
00011
00012
00013
00014
00015 MAKE_PTR_SUBC(LMESH,BMESH);
00016 class LMESH : public BMESH {
00017
00018 public:
00019
00020 LMESH(int num_v=0, int num_e=0, int num_f=0);
00021
00022 virtual ~LMESH();
00023
00024
00025 DEFINE_RTTI_METHODS3("LMESH", LMESH*, BMESH, CDATA_ITEM*);
00026
00027
00028
00029
00030 void delete_subdiv_mesh();
00031
00032
00033 void mark_all_dirty();
00034
00035
00036 CBvert_list& dirty_verts() const { return _dirty_verts; }
00037
00038
00039 Lvert* lv(int k) const { return (Lvert*) _verts[k]; }
00040 Ledge* le(int k) const { return (Ledge*) _edges[k]; }
00041 Lface* lf(int k) const { return (Lface*) _faces[k]; }
00042
00043 Lvert* dv(int k) const { return (Lvert*) _dirty_verts[k]; }
00044
00045
00046
00047
00048 LMESH* control_mesh() const {
00049 return (LMESH*) (_parent_mesh ? _parent_mesh->control_mesh() : this);
00050 }
00051
00052 bool is_control_mesh() const { return (_parent_mesh == 0); }
00053
00054
00055 LMESH* subdiv_mesh() const { return (LMESH*)_subdiv_mesh; }
00056
00057
00058 LMESH* parent_mesh() const { return (LMESH*)_parent_mesh; }
00059
00060
00061
00062 LMESH* subdiv_mesh(int k) const {
00063 if (k == 0)
00064 return (LMESH*)this;
00065 else if (k < 0)
00066 return parent_mesh(-k);
00067 else
00068 return _subdiv_mesh ? _subdiv_mesh->subdiv_mesh(k-1) : 0;
00069 }
00070
00071
00072
00073 LMESH* parent_mesh(int k) const {
00074 if (k == 0)
00075 return (LMESH*)this;
00076 else if (k < 0)
00077 return subdiv_mesh(-k);
00078 else
00079 return _parent_mesh ? _parent_mesh->parent_mesh(k-1) : 0;
00080 }
00081
00082
00083
00084 bool allocate_subdiv_mesh();
00085
00086
00087 LMESH* cur_mesh() const { return control_mesh()->_cur_mesh; }
00088
00089 bool is_cur_mesh() const { return cur_mesh() == this; }
00090
00091
00092
00093 int subdiv_face_scale() const { return (1 << 2*cur_level()); }
00094
00095
00096
00097 int subdiv_edge_scale() const { return (1 << cur_level()); }
00098
00099
00100 SubdivLocCalc* loc_calc() const { return _loc_calc; }
00101 SubdivColorCalc* color_calc() const { return _color_calc; }
00102
00103 void set_subdiv_loc_calc(SubdivLocCalc* c);
00104 void set_subdiv_color_calc(SubdivColorCalc* c);
00105
00106 Wpt limit_loc (CBvert* v) const { return _loc_calc->limit_val(v); }
00107 Wpt subdiv_loc (CBvert* v) const { return _loc_calc->subdiv_val(v); }
00108 Wpt subdiv_loc (CBedge* e) const { return _loc_calc->subdiv_val(e); }
00109 COLOR subdiv_color(CBvert* v) const { return _color_calc->subdiv_val(v); }
00110 COLOR subdiv_color(CBedge* e) const { return _color_calc->subdiv_val(e); }
00111
00112
00113 void refine();
00114 void unrefine();
00115
00116
00117
00118
00119 bool update_subdivision(int level);
00120
00121
00122
00123
00124 static bool update_subdivision(CBface_list& faces, int k=1);
00125
00126
00127 static bool update_subdivision(CBvert_list& verts, int k=1) {
00128 return update_subdivision(verts.one_ring_faces(), k);
00129 }
00130
00131
00132 void update() {
00133 if (_cur_mesh != this)
00134 update_subdivision(cur_level());
00135 }
00136
00137
00138 void subdivide_in_place();
00139
00140
00141
00142 void add_dirty_vert(Lvert* v) {
00143 if (v && v->is_clear(Lvert::DIRTY_VERT_LIST_BIT)) {
00144 v->set_bit(Lvert::DIRTY_VERT_LIST_BIT);
00145 _dirty_verts += v;
00146 }
00147 }
00148 void rem_dirty_vert(Lvert* v) {
00149 if (v && v->is_set(Lvert::DIRTY_VERT_LIST_BIT)) {
00150 v->clear_bit(Lvert::DIRTY_VERT_LIST_BIT);
00151 _dirty_verts -= v;
00152 }
00153 }
00154
00155 static void fit(ARRAY<Lvert*>& verts, bool do_gauss_seidel=1);
00156
00157
00158
00159
00160 static LMESHptr merge(LMESHptr m1, LMESHptr m2) {
00161 BMESHptr ret = BMESH::merge(m1, m2);
00162 return ret ? (LMESH*)&*ret : 0;
00163 }
00164
00165
00166
00167
00168 static Bvert_list get_subdiv_inputs(CBvert_list& verts);
00169
00170
00171
00172
00173
00174 static LMESHptr read_jot_file (char* filename);
00175 static LMESHptr read_jot_stream(istream& is);
00176
00177
00178
00179
00180 virtual int cur_level() const { return cur_mesh()->_subdiv_level; }
00181
00182
00183
00184 virtual int subdiv_level() const { return _subdiv_level; }
00185
00186
00187
00188 int max_cur_level() const { return control_mesh()->_max_cur_level(); }
00189
00190
00191 virtual CBvert_list& cur_verts() const { return cur_mesh()->verts(); }
00192 virtual CBedge_list& cur_edges() const { return cur_mesh()->edges(); }
00193 virtual CBface_list& cur_faces() const { return cur_mesh()->faces(); }
00194
00195
00196 virtual Bvert* new_vert(CWpt& p = mlib::Wpt::Origin()) const;
00197 virtual Bedge* new_edge(Bvert* u, Bvert* v) const;
00198 virtual Bface* new_face(Bvert*,Bvert*,Bvert*,Bedge*,Bedge*,Bedge*) const;
00199
00200
00201 virtual TriStrip* new_tri_strip() const { return new TriStrip; }
00202
00203 virtual EdgeStrip* new_edge_strip() const { return new LedgeStrip; }
00204 virtual VertStrip* new_vert_strip() const { return new LvertStrip; }
00205 virtual Patch* new_patch();
00206
00207
00208 virtual Bvert* add_vertex(Bvert* v);
00209 virtual Bvert* add_vertex(CWpt& loc=mlib::Wpt::Origin());
00210
00211
00212 virtual int remove_vertex(Bvert* v);
00213 virtual int remove_edge(Bedge* e);
00214 virtual int remove_face(Bface* f);
00215
00216
00217 virtual double volume() const;
00218 virtual double area() const;
00219 virtual void clear_creases();
00220
00221
00222 virtual void delete_elements();
00223
00224
00225 virtual BMESH& operator =(CBMESH& m);
00226 virtual BMESH& operator =(CLMESH& m);
00227 virtual BMESH& operator =(BODY& b);
00228
00229
00230 virtual void set_geom(GEOM *geom);
00231
00232
00233 virtual int write_patches(ostream& os) const;
00234
00235
00236
00237
00238
00239 virtual int edit_level() const {
00240 return control_mesh()->BMESH::edit_level();
00241 }
00242
00243 virtual void inc_edit_level();
00244 virtual void dec_edit_level();
00245
00246
00247
00248 virtual bool set_edit_level(int level);
00249
00250 virtual void changed(change_t);
00251 virtual void changed() { changed(TOPOLOGY_CHANGED); }
00252
00253
00254
00255
00256 virtual int size() const;
00257 virtual void print() const;
00258
00259
00260
00261
00262
00263
00264
00265 virtual void set_render_style(Cstr_ptr& s) {
00266 control_mesh()->BMESH::set_render_style(s);
00267 }
00268 virtual void push_render_style(Cstr_ptr& s) {
00269 control_mesh()->BMESH::push_render_style(s);
00270 }
00271 virtual void pop_render_style() {
00272 control_mesh()->BMESH::pop_render_style();
00273 }
00274 virtual Cstr_ptr& render_style() const {
00275 return control_mesh()->BMESH::render_style();
00276 }
00277
00278
00279
00280 virtual int draw(CVIEWptr &v);
00281 virtual int intersect(RAYhit&, CWtransf&, mlib::Wpt&,
00282 Wvec&, double&, double&,mlib::XYpt&) const;
00283 virtual void transform(CWtransf &xform, CMOD& m);
00284 virtual BODY *subtract (BODYptr &subtractor) { return 0; }
00285 virtual BODY *combine (BODYptr &combiner) { return 0; }
00286 virtual BODY *intersect (BODYptr &intersector) { return 0; }
00287 virtual CBBOX &get_bb();
00288
00289
00290
00291 virtual CTAGlist &tags() const;
00292
00293 virtual DATA_ITEM *dup() const { return new LMESH(0,0,0);}
00294
00295
00296
00297
00298 protected:
00299 LMESH* _parent_mesh;
00300 LMESH* _cur_mesh;
00301 LMESHptr _subdiv_mesh;
00302 int _subdiv_level;
00303 Bvert_list _dirty_verts;
00304
00305
00306 SubdivLocCalc* _loc_calc;
00307 SubdivColorCalc* _color_calc;
00308
00309
00310
00311 void set_parent(LMESH* parent) {
00312 _parent_mesh = parent;
00313 _subdiv_level = parent->subdiv_level() + 1;
00314 }
00315
00316 void set_cur_mesh(LMESH* cur);
00317
00318
00319
00320 int _max_cur_level() const {
00321 return _subdiv_mesh ? _subdiv_mesh->_max_cur_level() + 1 : 0;
00322 }
00323
00324 virtual void send_update_notification();
00325
00326
00327 virtual void _merge(BMESH*);
00328
00329
00330 TAGlist* _lmesh_tags;
00331 };
00332
00333
00334
00335
00336
00337
00338 inline LMESHptr
00339 gel_to_lmesh(CGELptr &gel)
00340 {
00341 BMESHptr mesh = gel_to_bmesh(gel);
00342 return mesh ? LMESH::upcast(&*mesh) : 0;
00343 }
00344
00345 inline BMESH*
00346 get_ctrl_mesh(CBMESH* m)
00347 {
00348 return (LMESH::isa(m)) ? ((LMESH*)m)->control_mesh() : (BMESH*)m;
00349 }
00350
00351 inline BMESH*
00352 get_cur_mesh(CBMESH* m)
00353 {
00354 return (LMESH::isa(m)) ? ((LMESH*)m)->control_mesh()->cur_mesh() :
00355 (BMESH*)m;
00356 }
00357
00358
00359 inline LMESH*
00360 get_lmesh(CBsimplex* s)
00361 {
00362 return s ? LMESH::upcast(s->mesh()) : 0;
00363 }
00364
00365 inline int
00366 subdiv_level(CBsimplex* s)
00367 {
00368 if (!s) return -1;
00369 LMESH* m = LMESH::upcast(s->mesh());
00370 return m ? m->subdiv_level() : -1;
00371 }
00372
00373 inline Bface*
00374 get_ctrl_face(CBface* f)
00375 {
00376 if (!f)
00377 return 0;
00378 return LMESH::isa(f->mesh()) ? ((Lface*)f)->control_face() : (Bface*)f;
00379 }
00380
00381 inline Bface*
00382 get_parent_face(CBface* f)
00383 {
00384 return (f && LMESH::isa(f->mesh())) ? ((Lface*)f)->parent() : 0;
00385 }
00386
00387 inline Bsimplex*
00388 get_parent_simplex(CBedge* e)
00389 {
00390 return (e && LMESH::isa(e->mesh())) ? ((Ledge*)e)->parent() : 0;
00391 }
00392
00393 inline Bsimplex*
00394 get_parent_simplex(CBvert* v)
00395 {
00396 return (v && LMESH::isa(v->mesh())) ? ((Lvert*)v)->parent() : 0;
00397 }
00398
00399 inline Bsimplex*
00400 get_parent_simplex(CBsimplex* s)
00401 {
00402 return (!(s && LMESH::isa(s->mesh())) ? 0 :
00403 is_vert(s) ? get_parent_simplex((Bvert*)s) :
00404 is_edge(s) ? get_parent_simplex((Bedge*)s) :
00405 is_face(s) ? (Bsimplex*)get_parent_face((Bface*)s) :
00406 0);
00407 }
00408
00409 inline void
00410 claim_edit_level(LMESHptr m)
00411 {
00412
00413
00414
00415 if (m) {
00416 m->control_mesh()->update_subdivision(m->subdiv_level());
00417 set_edit_level(m, m->subdiv_level());
00418 }
00419 }
00420
00421 inline void
00422 update_subdivision(CBMESHptr& mesh, int level)
00423 {
00424 if (mesh && LMESH::isa(&*mesh)) {
00425 LMESH* ctrl = ((LMESH*)&*mesh)->control_mesh();
00426 if (ctrl)
00427 ctrl->update_subdivision(level);
00428 }
00429 }
00430
00431 inline LMESH*
00432 get_lmesh(CBface_list& faces)
00433 {
00434 return LMESH::upcast(faces.mesh());
00435 }
00436
00437 inline LMESH*
00438 get_subdiv_mesh(BMESH* m, int level)
00439 {
00440
00441 if ( level < 0 || !LMESH::isa(m) )
00442 return 0;
00443
00444 LMESH* lm = (LMESH*)m;
00445
00446 for ( int i=0; lm && i<level; i++ ) {
00447 lm = lm->subdiv_mesh();
00448 }
00449
00450 return lm;
00451 }
00452
00453
00454
00455 inline Bface_list
00456 get_subdiv_faces(CBface_list& faces, int level)
00457 {
00458 Bface_list ret;
00459 LMESH* m = LMESH::upcast(faces.mesh());
00460 if (!(level >= 0 && m && m->subdiv_mesh(level)))
00461 return ret;
00462 for (int i=0; i<faces.num(); i++)
00463 ((Lface*)faces[i])->append_subdiv_faces(level, ret);
00464 return ret;
00465 }
00466
00467
00468
00469 inline Bface_list
00470 get_parent_faces(CBface_list& faces, int level=1)
00471 {
00472 Bface_list ret;
00473 LMESH* m = LMESH::upcast(faces.mesh());
00474 if (!(level >= 0 && m && m->parent_mesh(level)))
00475 return ret;
00476
00477
00478 Lface* p = 0;
00479 int i;
00480 for (i = 0; i<faces.num(); i++) {
00481 if ((p = ((Lface*)faces[i])->parent()))
00482 p->clear_flag();
00483 }
00484
00485
00486 for (i = 0; i<faces.num(); i++) {
00487 if ((p = ((Lface*)faces[i])->parent()) && !p->flag()) {
00488 p->set_flag(1);
00489 ret += p;
00490 }
00491 }
00492 return ret;
00493 }
00494
00495 inline Bface_list
00496 remap_level(CBface_list& faces, int k)
00497 {
00498
00499
00500
00501
00502 if (k == 0)
00503 return faces;
00504 else if (k < 0)
00505 return get_parent_faces(faces, -k);
00506 else
00507 return get_subdiv_faces(faces, k);
00508 }
00509
00510 inline Bface_list
00511 get_top_level(CBface_list& faces)
00512 {
00513 Bface_list ret = faces;
00514
00515 for (Bface_list p = get_parent_faces(faces);
00516 !p.empty();
00517 p = get_parent_faces(p))
00518 ret = p;
00519 return ret;
00520 }
00521
00522 inline bool
00523 has_secondary_any_level(CBface_list& faces)
00524 {
00525 for (Bface_list sub = faces; !sub.empty(); sub = get_subdiv_faces(sub,1))
00526 if (sub.has_any_secondary())
00527 return true;
00528 return false;
00529 }
00530
00531 template <class L, class S>
00532 inline Bvert_list
00533 child_verts(const L& list)
00534 {
00535
00536
00537
00538
00539
00540
00541
00542
00543 Bvert_list ret(list.num());
00544
00545 if (list.empty())
00546 return ret;
00547
00548 assert(LMESH::isa(list.mesh()));
00549
00550 for (int i=0; i<list.num(); i++) {
00551 Lvert* v = ((S*)list[i])->subdiv_vertex();
00552 assert(v);
00553 ret += v;
00554 }
00555 return ret;
00556 }
00557
00558 #endif // LMESH_H_HAS_BEEN_INCLUDED
00559
00560