00001
00002
00003
00004 #include "std/fstream.H"
00005 #include "std/run_avg.H"
00006 #include "std/stop_watch.H"
00007 #include "std/config.H"
00008
00009 #include "disp/ray.H"
00010 #include "net/io_manager.H"
00011
00012 #include "mesh/patch.H"
00013 #include "mesh/uv_data.H"
00014 #include "mesh/base_ref_image.H"
00015 #include "mesh/ioblock.H"
00016 #include "mesh/gtexture.H"
00017 #include "mesh/bfilters.H"
00018 #include "mesh/lmesh.H"
00019
00020 using namespace mlib;
00021
00022
00023 str_ptr BODY::_base_name = BMESH::static_name();
00024 TAGlist BODY::_body_tags;
00025
00026
00027
00028
00029 static int dummy = BODY::set_factory(new BMESH);
00030
00031 bool BMESH::_random_sils = !Config::get_var_bool("NO_RANDOM_SILS",false);
00032 bool BMESH::_freeze_sils = false;
00033 TAGlist* BMESH::_bmesh_tags = NULL;
00034 TAGlist* BMESH::_bmesh_update_tags = NULL;
00035 BMESH* BMESH::_center_of_interest = 0;
00036 bool BMESH::_show_secondary_faces = false;
00037
00038 bool use_new_bface_io = Config::get_var_bool("JOT_USE_NEW_BFACE_IO",true);
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 BMESHobs_list BMESHobs::_all_observers(32);
00049 HASH BMESHobs::_hash(300);
00050
00051 static class DECODERS
00052 {
00053 public:
00054 DECODERS() {
00055 DECODER_ADD(BMESH);
00056 DECODER_ADD(LMESH);
00057 }
00058 }
00059 DECODERS_static;
00060
00061 BMESH::BMESH(int num_v, int num_e, int num_f) :
00062 _verts(num_v),
00063 _edges(num_e),
00064 _faces(num_f),
00065 _version(1),
00066 _creases(0),
00067 _borders(0),
00068 _polylines(0),
00069 _lone_verts(0),
00070 _sil_stamp(0),
00071 _zx_stamp(0),
00072 _draw_enabled(1),
00073 _pix_size(0),
00074 _pix_size_stamp(0),
00075 _type(EMPTY_MESH),
00076 _type_valid(1),
00077 _geom(0),
00078 _pm_stamp(0),
00079 _eye_local_stamp(0),
00080 _curv_data(0),
00081 _avg_edge_len(0),
00082 _avg_edge_len_valid(0),
00083 _edit_level(0)
00084 {
00085 begin_index();
00086 _drawables.set_unique();
00087 }
00088
00089 BMESH::BMESH(CBMESH& m) :
00090 _version(1),
00091 _polylines(0),
00092 _lone_verts(0),
00093 _sil_stamp(0),
00094 _zx_stamp(0),
00095 _draw_enabled(1),
00096 _pix_size(0),
00097 _pix_size_stamp(0),
00098 _type(EMPTY_MESH),
00099 _type_valid(1),
00100 _geom(0),
00101 _pm_stamp(0),
00102 _eye_local_stamp(0),
00103 _curv_data(0),
00104 _avg_edge_len(0),
00105 _avg_edge_len_valid(0),
00106 _edit_level(0)
00107 {
00108 begin_index();
00109 _drawables.set_unique();
00110
00111 *this = m;
00112 }
00113
00114 BMESH::~BMESH()
00115 {
00116 static bool debug = Config::get_var_bool("DEBUG_BMESH_DESTRUCTOR",false);
00117 if (debug)
00118 err_msg("BMESH::~BMESH called...");
00119
00120
00121 BMESHobs::broadcast_delete(this);
00122
00123
00124 end_index();
00125
00126
00127 delete_elements();
00128
00129 if (is_center_of_interest(this))
00130 set_center_of_interest(0);
00131 }
00132
00133 void
00134 BMESH::begin_index()
00135 {
00136 _verts.begin_index();
00137 _edges.begin_index();
00138 _faces.begin_index();
00139 }
00140
00141
00142 void
00143 BMESH::end_index()
00144 {
00145 _verts.end_index();
00146 _edges.end_index();
00147 _faces.end_index();
00148 }
00149
00150 Bvert*
00151 BMESH::add_vertex(Bvert* v)
00152 {
00153 if (v) {
00154 v->set_mesh(this);
00155 _verts += v;
00156 } else
00157 err_msg("BMESH::add_vertex:: error: vertex is nil");
00158 return v;
00159 }
00160
00161 Bvert*
00162 BMESH::add_vertex(CWpt& loc)
00163 {
00164 return add_vertex(new_vert(loc));
00165 }
00166
00167 Bvert_list
00168 BMESH::add_verts(CWpt_list& pts)
00169 {
00170 Bvert_list ret(pts.num());
00171 for (int i=0; i<pts.num(); i++)
00172 ret += add_vertex(pts[i]);
00173 return ret;
00174 }
00175
00176 Bedge*
00177 BMESH::add_edge(Bedge* e)
00178 {
00179 if (e) {
00180 e->set_mesh(this);
00181 _edges += e;
00182 } else
00183 err_msg("BMESH::add_edge:: error: edge is nil");
00184 return e;
00185 }
00186
00187 Bedge*
00188 BMESH::add_edge(Bvert* u, Bvert* v)
00189 {
00190 if (!(u && v)) {
00191 err_msg("BMESH::add_edge: Error: vertices are nil");
00192 } else if (u == v) {
00193 err_msg("BMESH::add_edge: Error: repeated vertex");
00194 } else if (!((u->mesh() == this) && (v->mesh() == this))) {
00195 err_msg("BMESH::add_edge: Error: foreign vertices not allowed");
00196 } else {
00197 Bedge* ret = u->lookup_edge(v);
00198 return ret ? ret : add_edge(new_edge(u,v));
00199 }
00200 return 0;
00201 }
00202
00203 Bedge*
00204 BMESH::add_edge(int i, int j)
00205 {
00206 Bedge* ret = 0;
00207 if (valid_vert_indices(i,j))
00208 ret = add_edge(_verts[i],_verts[j]);
00209 else
00210 err_msg("BMESH::add_edge: invalid vertex indices (%d,%d)", i, j);
00211 return ret;
00212 }
00213
00214 Bedge*
00215 BMESH::lookup_edge (const Point2i &p)
00216 {
00217 if (!(_verts.valid_index(p[0]) && _verts.valid_index(p[1])))
00218 return 0;
00219 return (::lookup_edge (bv(p[0]), bv(p[1])));
00220
00221 }
00222
00223
00224 Bface*
00225 BMESH::add_face(Bface* f, Patch* p)
00226 {
00227 if (!f) {
00228 err_msg("BMESH::add_face: error: face is nil");
00229 return 0;
00230 }
00231
00232 f->set_mesh(this);
00233 _faces += f;
00234
00235
00236
00237 if (p && p->mesh() != this) {
00238 cerr << "BMESH::add_face: error: patch specified "
00239 << "belongs to a different mesh" << endl;
00240 p = 0;
00241 }
00242
00243
00244 if (p)
00245 p->add(f);
00246
00247 return f;
00248 }
00249
00250 Bface*
00251 BMESH::add_face(Bvert* u, Bvert* v, Bvert* w, Patch* p)
00252 {
00253
00254 if (!(u && v && w)) {
00255 err_msg("BMESH::add_face: Error: vertices are nil");
00256 return 0;
00257 } else if (u==v || u==w || v==w) {
00258 err_msg("BMESH::add_face: Error: repeated vertex");
00259 return 0;
00260 }
00261 if (!((u->mesh() == this) && (v->mesh() == this) && (w->mesh() == this))) {
00262 err_msg("BMESH::add_face: Error: foreign vertices not allowed");
00263 return 0;
00264 }
00265
00266
00267 Bface* tmp = ::lookup_face(u,v,w);
00268 if (tmp) {
00269
00270
00271
00272 return tmp;
00273 }
00274
00275
00276 Bedge *e1=add_edge(u,v), *e2=add_edge(v,w), *e3=add_edge(w,u);
00277 if (!(e1 && e2 && e3)) {
00278 err_msg("BMESH::add_face: Error: can't create edges");
00279 return 0;
00280 }
00281 return add_face(new_face(u,v,w,e1,e2,e3), p);
00282 }
00283
00284 Bface*
00285 BMESH::add_face(int i, int j, int k, Patch* p)
00286 {
00287 if (!valid_vert_indices(i,j,k)) {
00288 err_msg("BMESH::add_face: Error: invalid vertex indices (%d,%d,%d)",
00289 i, j, k);
00290 return 0;
00291 }
00292 return add_face(_verts[i],_verts[j],_verts[k], p);
00293 }
00294
00295 Bface*
00296 BMESH::add_face(Bvert* u, Bvert* v, Bvert* w, CUVpt& a, CUVpt& b, CUVpt& c, Patch* p)
00297 {
00298 Bface* ret = add_face(u,v,w,p);
00299 if (ret)
00300 UVdata::set
00301 (ret, u, v, w, a, b, c);
00302 return ret;
00303 }
00304
00305 Bface*
00306 BMESH::add_face(int i, int j, int k, CUVpt& a, CUVpt& b, CUVpt& c, Patch* p)
00307 {
00308 Bface* ret = add_face(i,j,k,p);
00309 if (ret)
00310 UVdata::set
00311 (ret, _verts[i], _verts[j], _verts[k], a, b, c);
00312 return ret;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 Bface*
00331 BMESH::add_quad(Bvert* u, Bvert* v, Bvert* w, Bvert* x, Patch* p)
00332 {
00333 Bface* f1 = add_face(u,v,w,p);
00334 Bface* f2 = add_face(u,w,x,p);
00335
00336 if (f1 && f2) {
00337 Bedge* weak_edge = u->lookup_edge(w);
00338 assert(weak_edge);
00339 weak_edge->set_bit(Bedge::WEAK_BIT);
00340 assert(f1->is_quad());
00341 return f1->quad_rep();
00342 }
00343 if (f1 || f2)
00344 err_msg("BMESH::add_quad: Error: created one face, not the other");
00345 else
00346 err_msg("BMESH::add_quad: Error: couldn't create either face");
00347 return 0;
00348 }
00349
00350 Bface*
00351 BMESH::add_quad(
00352 Bvert* u, Bvert* v, Bvert* w, Bvert* x,
00353 CUVpt& a, CUVpt& b, CUVpt& c, CUVpt& d, Patch* p)
00354 {
00355 Bface* ret = add_quad(u,v,w,x,p);
00356
00357 if (ret && !UVdata::set
00358 (u,v,w,x,a,b,c,d))
00359 err_msg("BMESH::add_quad: Error: could not set UV coordinates");
00360
00361 return ret;
00362 }
00363
00364 Bface*
00365 BMESH::add_quad(int i, int j, int k, int l, Patch* p)
00366 {
00367 return (
00368 valid_vert_indices(i,j,k,l) ?
00369 add_quad(_verts[i],_verts[j],_verts[k],_verts[l],p) :
00370 0);
00371 }
00372
00373 Bface*
00374 BMESH::add_quad(int i, int j, int k, int l,
00375 CUVpt& a, CUVpt& b, CUVpt& c, CUVpt& d, Patch* p)
00376 {
00377 return (
00378 valid_vert_indices(i,j,k,l) ?
00379 add_quad(_verts[i],_verts[j],_verts[k],_verts[l],a,b,c,d,p) :
00380 0);
00381 }
00382
00383 Bface*
00384 BMESH::lookup_face (const Point3i &p)
00385 {
00386 if (!(_verts.valid_index(p[0]) && _verts.valid_index(p[1])&&
00387 _verts.valid_index(p[2]))) {
00388 cerr << "BMESH::lookup_face - invalid vert index\n";
00389 return 0;
00390 }
00391 return (::lookup_face (bv(p[0]), bv(p[1]), bv(p[2])));
00392
00393 }
00394
00395
00396 void
00397 BMESH::Cube(CWpt& a, CWpt& b, Patch* p)
00398 {
00399
00400
00401
00402
00403 Wvec diag = (b - a);
00404 Wvec dx(diag[0],0,0);
00405 Wvec dy(0,diag[1],0);
00406 Wvec dz(0,0,diag[2]);
00407
00408
00409 add_vertex(a + dz);
00410 add_vertex(a);
00411 add_vertex(a + dx + dz);
00412 add_vertex(a + dx);
00413 add_vertex(a + dx + dy + dz);
00414 add_vertex(a + dx + dy);
00415 add_vertex(a + dy + dz);
00416 add_vertex(a + dy);
00417
00418
00419 UVpt u00(0,0), u10(1,0), u11(1,1), u01(0,1);
00420
00421
00422 if (p && p->mesh() != this) {
00423 err_msg("BMESH::Cube: foreign patch, rejecting...");
00424 p = 0;
00425 }
00426 if (!p)
00427 p = new_patch();
00428
00429
00430 add_quad(0,1,3,2,u00,u10,u11,u01,p);
00431 add_quad(2,3,5,4,u00,u10,u11,u01,p);
00432 add_quad(4,5,7,6,u00,u10,u11,u01,p);
00433 add_quad(6,7,1,0,u00,u10,u11,u01,p);
00434 add_quad(6,0,2,4,u00,u10,u11,u01,p);
00435 add_quad(5,3,1,7,u00,u10,u11,u01,p);
00436
00437 changed(TOPOLOGY_CHANGED);
00438 }
00439
00440 void
00441 BMESH::Octahedron(CWpt& bot, CWpt& m0, CWpt& m1,
00442 CWpt& m2, CWpt& m3, CWpt& top, Patch* p)
00443 {
00444
00445
00446
00447 add_vertex(bot);
00448 add_vertex(m0);
00449 add_vertex(m1);
00450 add_vertex(m2);
00451 add_vertex(m3);
00452 add_vertex(top);
00453
00454
00455 if (p && p->mesh() != this) {
00456 err_msg("BMESH::Octahedron: foreign patch, rejecting...");
00457 p = 0;
00458 }
00459 if (!p)
00460 p = new_patch();
00461
00462 add_face(0,1,4,p);
00463 add_face(0,2,1,p);
00464 add_face(0,3,2,p);
00465 add_face(0,4,3,p);
00466
00467 add_face(5,1,2,p);
00468 add_face(5,2,3,p);
00469 add_face(5,3,4,p);
00470 add_face(5,4,1,p);
00471
00472 changed(TOPOLOGY_CHANGED);
00473 }
00474
00475
00476
00477
00478
00479 void
00480 BMESH::Sphere(Patch* p)
00481 {
00482
00483
00484
00485
00486
00487 const int RESOLUTION = 16;
00488
00489
00490
00491
00492
00493
00494
00495
00496 for (int i=0; i<(RESOLUTION+1); i++) {
00497 for (int j=0; j<(RESOLUTION*2); j++) {
00498
00499 double alpha = (double(j)/double(RESOLUTION*2))*TWO_PI;
00500 double beta = (double(i)/double(RESOLUTION))*M_PI;
00501
00502
00503 double x = sin(alpha) * sin(beta);
00504 double y = cos(beta);
00505 double z = cos(alpha) * sin(beta);
00506
00507 add_vertex(Wpt(x,y,z));
00508
00509 if((beta==0)||(beta==M_PI))
00510 break;
00511 }
00512 }
00513
00514 if (p && p->mesh() != this) {
00515 err_msg("BMESH::Sphere: foreign patch, rejecting...");
00516 p = 0;
00517 }
00518 if (!p)
00519 p = new_patch();
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 for (int i=1; i<=(RESOLUTION*2); i++)
00531 add_face(0,i,((i)%(RESOLUTION*2)+1) ,
00532 UVpt((double(i)/double(RESOLUTION*2)),1.0),
00533 UVpt((double(i)/double(RESOLUTION*2)),1.0 -(1.0/double(RESOLUTION+1))),
00534 UVpt((double(i+1)/double(RESOLUTION*2)),1.0 -(1.0/double(RESOLUTION+1))),
00535 p);
00536
00537
00538 int start=((RESOLUTION-2)*((RESOLUTION*2))+1);
00539 int stop= ((RESOLUTION-1)*((RESOLUTION*2)));
00540
00541 for (int i=start; i<=stop; i++)
00542 add_face((RESOLUTION-1)*((RESOLUTION*2))+1,i,(i==stop ? start : i+1),
00543 UVpt((double(i)/double(RESOLUTION*2)),0.0),
00544 UVpt((double(i+1)/double(RESOLUTION*2)),1.0 -(double(RESOLUTION-1)/double(RESOLUTION+1))),
00545 UVpt((double(i)/double(RESOLUTION*2)),1.0 -(double(RESOLUTION-1)/double(RESOLUTION+1))),
00546 p);
00547
00548
00549
00550 for (int j=0; j<(RESOLUTION-2); j++) {
00551 for (int i=1; i<=(RESOLUTION*2); i++) {
00552 int k = ((RESOLUTION*2)*j)+(i);
00553 if (i!= (RESOLUTION*2)) {
00554 add_quad(k,k+(RESOLUTION*2),((k+1))+(RESOLUTION*2),((k+1)),
00555 UVpt((double(i)/double(RESOLUTION*2)),1.0-(double(j+1)/double(RESOLUTION+1))),
00556 UVpt((double(i)/double(RESOLUTION*2)),1.0-(double(j+2)/double(RESOLUTION+1))),
00557 UVpt((double(i+1)/double(RESOLUTION*2)),1.0-(double(j+2)/double(RESOLUTION+1))),
00558 UVpt((double(i+1)/double(RESOLUTION*2)),1.0-(double(j+1)/double(RESOLUTION+1))),
00559 p);
00560 } else {
00561 add_quad(k,k+(RESOLUTION*2),((k+1)),((k+1))-(RESOLUTION*2),
00562 UVpt((double(i)/double(RESOLUTION*2)),1.0-(double(j+1)/double(RESOLUTION+1))),
00563 UVpt((double(i)/double(RESOLUTION*2)),1.0-(double(j+2)/double(RESOLUTION+1))),
00564 UVpt((double(i+1)/double(RESOLUTION*2)),1.0-(double(j+2)/double(RESOLUTION+1))),
00565 UVpt((double(i+1)/double(RESOLUTION*2)),1.0-(double(j+1)/double(RESOLUTION+1))),
00566 p);
00567 }
00568 }
00569 }
00570
00571 changed(TOPOLOGY_CHANGED);
00572 }
00573
00574 void
00575 BMESH::Icosahedron(Patch* p)
00576 {
00577
00578
00579
00580 add_vertex(Wpt(-.525731112119133606, 0, .850650808352039932));
00581 add_vertex(Wpt( .525731112119133606, 0, .850650808352039932));
00582 add_vertex(Wpt(-.525731112119133606, 0, -.850650808352039932));
00583 add_vertex(Wpt( .525731112119133606, 0, -.850650808352039932));
00584
00585 add_vertex(Wpt(0, .850650808352039932, .525731112119133606));
00586 add_vertex(Wpt(0, .850650808352039932, -.525731112119133606));
00587 add_vertex(Wpt(0, -.850650808352039932, .525731112119133606));
00588 add_vertex(Wpt(0, -.850650808352039932, -.525731112119133606));
00589
00590 add_vertex(Wpt( .850650808352039932, .525731112119133606, 0));
00591 add_vertex(Wpt(-.850650808352039932, .525731112119133606, 0));
00592 add_vertex(Wpt( .850650808352039932, -.525731112119133606, 0));
00593 add_vertex(Wpt(-.850650808352039932, -.525731112119133606, 0));
00594
00595
00596 if (p && p->mesh() != this) {
00597 err_msg("BMESH::Icosahedron: foreign patch, rejecting...");
00598 p = 0;
00599 }
00600 if (!p)
00601 p = new_patch();
00602
00603 add_face( 0, 1, 4, p);
00604 add_face( 0, 4, 9, p);
00605 add_face( 9, 4, 5, p);
00606 add_face( 4, 8, 5, p);
00607 add_face( 4, 1, 8, p);
00608 add_face( 8, 1, 10, p);
00609 add_face( 8, 10, 3, p);
00610 add_face( 5, 8, 3, p);
00611 add_face( 5, 3, 2, p);
00612 add_face( 2, 3, 7, p);
00613 add_face( 7, 3, 10, p);
00614 add_face( 7, 10, 6, p);
00615 add_face( 7, 6, 11, p);
00616 add_face(11, 6, 0, p);
00617 add_face( 0, 6, 1, p);
00618 add_face( 6, 10, 1, p);
00619 add_face( 9, 11, 0, p);
00620 add_face( 9, 2, 11, p);
00621 add_face( 9, 5, 2, p);
00622 add_face( 7, 11, 2, p);
00623
00624 changed(TOPOLOGY_CHANGED);
00625 }
00626
00627 double
00628 BMESH::area() const
00629 {
00630
00631
00632
00633
00634
00635 double ret = 0;
00636 for (int k=0; k<_faces.num(); k++)
00637 ret += _faces[k]->area();
00638
00639 return ret;
00640 }
00641
00642 double
00643 BMESH::volume() const
00644 {
00645
00646
00647
00648 double ret = 0;
00649 for (int k=0; k<_faces.num(); k++)
00650 ret += _faces[k]->volume_el();
00651
00652 return ret;
00653 }
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 int
00664 BMESH::size() const
00665 {
00666
00667 return (
00668 (nverts() * (sizeof(Bvert) + 6*sizeof(Bedge*) + 4)) +
00669 (nedges() * (sizeof(Bedge) + 4)) +
00670 (nfaces() * (sizeof(Bface) + 4)) +
00671 (npatches() * (sizeof(Patch) + 4)) +
00672 sizeof(BMESH)
00673 );
00674 }
00675
00676
00677 void
00678 BMESH::print() const
00679 {
00680 err_msg("%s: ", **class_name());
00681 err_msg("\tverts: %6d", _verts.num());
00682 err_msg("\tedges: %6d", _edges.num());
00683 err_msg("\tfaces: %6d", _faces.num());
00684 if (Config::get_var_bool("PRINT_MESH_SIZE",false))
00685 err_msg("\tMbytes used: %6.1lf", size()/1e6);
00686 cerr << "\ttype: ";
00687 if (is_points())
00688 cerr << "points ";
00689 if (is_polylines())
00690 cerr << "polylines ";
00691 if (is_open_surface())
00692 cerr << "open surface ";
00693 if (is_closed_surface())
00694 cerr << "closed surface ";
00695 cerr << endl;
00696 }
00697
00698 int
00699 BMESH::set_crease(int i, int j) const
00700 {
00701 Bedge* e = 0;
00702 if (valid_vert_indices(i,j) && (e = bv(i)->lookup_edge(bv(j))))
00703 e->set_crease();
00704 else
00705 err_msg("BMESH::set_crease: error: no such edge (%d,%d)", i, j);
00706 return e ? 1 : 0;
00707 }
00708
00709 int
00710 BMESH::set_weak_edge(int i, int j) const
00711 {
00712 Bedge* e = 0;
00713 if (valid_vert_indices(i,j) && (e = bv(i)->lookup_edge(bv(j))))
00714 e->set_bit(Bedge::WEAK_BIT);
00715 else
00716 err_msg("BMESH::set_weak_edge: error: no such edge (%d,%d)", i, j);
00717 return e ? 1 : 0;
00718 }
00719
00720 int
00721 BMESH::set_patch_boundary(int i, int j) const
00722 {
00723 Bedge* e = 0;
00724 if (valid_vert_indices(i,j) && (e = bv(i)->lookup_edge(bv(j))))
00725 e->set_patch_boundary();
00726 else
00727 err_msg("BMESH::set_patch_boundary: error: no such edge (%d,%d)", i, j);
00728 return e ? 1 : 0;
00729 }
00730
00731 Bface*
00732 BMESH::pick_face(
00733 CWline& world_ray,
00734 Wpt& world_hit
00735 ) const
00736 {
00737
00738
00739
00740
00741 static bool debug = Config::get_var_bool("DEBUG_PICK_FACE",false);
00742 if (debug)
00743 err_msg("BMESH::pick_face: doing brute force intersection");
00744
00745 Wpt p = inv_xform() * world_ray.point();
00746 Wvec n = inv_xform() * world_ray.vector();
00747
00748 Bface* ret = 0;
00749 double d, min_d = -1;
00750 Wpt h;
00751 for (int i=0; i<nfaces(); i++) {
00752 if (bf(i)->ray_intersect(p, n, h, d) && (!ret || d < min_d)) {
00753 min_d = d;
00754 ret = bf(i);
00755 world_hit = xform()*h;
00756 }
00757 }
00758 return ret;
00759 }
00760
00761 int
00762 BMESH::intersect(
00763 RAYhit &r,
00764 CWtransf &,
00765 Wpt &nearpt,
00766 Wvec &n,
00767 double &d,
00768 double &d2d,
00769 XYpt &uvc
00770 ) const
00771 {
00772
00773 BaseVisRefImage *vis_ref = BaseVisRefImage::lookup(VIEW::peek());
00774
00775
00776 static bool force_face_pick
00777 = Config::get_var_bool("FORCE_FACE_PICK",false);
00778
00779 if (force_face_pick || !r.from_camera() || !vis_ref) {
00780
00781 Bface* f = pick_face(r.line(), nearpt);
00782 if (!f)
00783 return 0;
00784
00785 d = nearpt.dist(r.point());
00786
00787
00788 if (_geom && r.test(d,1,0)) {
00789 uvc = XYpt(0,0);
00790 n = (inv_xform().transpose() * f->norm()).normalized();
00791 Wpt obj_pt = inv_xform() * nearpt;
00792 r.check(d, 1, 0, _geom, n, nearpt, obj_pt, f->patch(), uvc);
00793 BMESHray::set_simplex(r, f);
00794 } else {
00795 return 1;
00796 }
00797 }
00798
00799
00800 vis_ref->vis_update();
00801 Bsimplex* sim = vis_ref->vis_simplex(r.screen_point());
00802 if (!(sim && sim->mesh() == this)) {
00803 return 0;
00804 }
00805
00806 Wvec norm;
00807 if (sim->view_intersect(r.screen_point(),nearpt,d,d2d,norm) &&
00808 r.test(d,1,0)) {
00809 uvc = XYpt();
00810 n = norm;
00811
00812
00813
00814 Patch* p = get_ctrl_patch(sim);
00815
00816 r.check(d, 1, d2d, _geom, n, nearpt, inv_xform()*nearpt, p, uvc);
00817 BMESHray::set_simplex(r, sim);
00818 return 1;
00819 }
00820
00821 return 0;
00822 }
00823
00824 void
00825 BMESH::clear_creases()
00826 {
00827 bool changed_occurred = 0;
00828 for (int i=0; i<_edges.num(); i++) {
00829 if (be(i)->is_crease()) {
00830 be(i)->set_crease(0);
00831 changed_occurred=1;
00832 }
00833 }
00834
00835 if (changed_occurred)
00836 changed(CREASES_CHANGED);
00837 }
00838
00839 void
00840 BMESH::compute_creases()
00841 {
00842 double thresh = Config::get_var_dbl("JOT_CREASE_THRESH", 0.5, true);
00843
00844 for (int k = 0; k < _edges.num(); k++)
00845 be(k)->compute_crease(thresh);
00846
00847 changed(CREASES_CHANGED);
00848 }
00849
00850 int
00851 BMESH::build_polyline_strips()
00852 {
00853
00854
00855
00856
00857
00858
00859 if (_polylines)
00860 _polylines->reset();
00861 else
00862 _polylines = new_edge_strip();
00863
00864
00865
00866 make_patch_if_needed();
00867 _patches[0]->add
00868 (_polylines);
00869
00870
00871
00872
00873 ARRAY<Bedge*> polyline_edges(1024);
00874 ARRAY<Bedge*> polyline_ends (128);
00875 int k;
00876 for (k=0; k<_edges.num(); k++) {
00877
00878 _edges[k]->clear_flag();
00879 if (_edges[k]->is_polyline()) {
00880
00881
00882 if (_edges[k]->is_polyline_end())
00883 polyline_ends += _edges[k];
00884 else
00885 polyline_edges += _edges[k];
00886 }
00887 }
00888
00889
00890 polyline_edges += polyline_ends;
00891
00892
00893 UnreachedSimplexFilter unreached;
00894 PolylineEdgeFilter polyline;
00895 AndFilter wanted = unreached + polyline;
00896 for (k=polyline_edges.num()-1; k>=0; k--) {
00897 Bedge* e = polyline_edges[k];
00898 Bvert* v = e->v2()->is_polyline_end() ? e->v2() : e->v1();
00899 _polylines->build(v, e, wanted);
00900 }
00901
00902 err_msg("BMESH::build_polyline_strips: got %d edges",
00903 _polylines->edges().num());
00904 err_msg("Warning: BMESH does not currently draw polylines");
00905
00906 return _polylines->num();
00907 }
00908
00909 int
00910 BMESH::build_vert_strips()
00911 {
00912
00913
00914
00915
00916
00917
00918 if (_lone_verts)
00919 _lone_verts->reset();
00920 else
00921 _lone_verts = new_vert_strip();
00922
00923
00924
00925 if (_patches.empty())
00926 new_patch();
00927 _patches[0]->add
00928 (_lone_verts);
00929
00930 for (int k=0; k<_verts.num(); k++)
00931 if (bv(k)->degree() == 0)
00932 _lone_verts->add
00933 (bv(k));
00934
00935 return _lone_verts->num();
00936 }
00937
00938 int
00939 BMESH::build_zcross_strips()
00940 {
00941
00942
00943
00944 static bool HACK_EYE_POS = Config::get_var_bool("HACK_EYE_POS",false);
00945 static bool DEBUGADAPT = Config::get_var_bool("DEBUG_ADAPTIVE",false);
00946 if ((!(HACK_EYE_POS || DEBUGADAPT ) && ( _zx_stamp == VIEW::stamp())) ||
00947 nfaces() == 0 || _freeze_sils)
00948 return 0;
00949
00950 static bool debug = Config::get_var_bool("DEBUG_BUILD_ZX_STRIPS",false);
00951 if (debug)
00952 err_msg("BMESH::build_zcross_strips: frame number %d",
00953 (int)VIEW::stamp());
00954
00955
00956 int k;
00957 for (k = 0; k<_patches.num(); k++)
00958 _patches[k]->zx_sils().reset();
00959
00960
00961 get_zcross_strips();
00962
00963 if (_zx_sils.empty())
00964 return 0;
00965
00966
00967 Patch* p = 0;
00968 Patch* lp = _zx_sils.seg(0).f()->patch();
00969 assert (lp != NULL);
00970
00971
00972 for (k = 0; k < _zx_sils.num(); k++) {
00973
00974 Bface* f = _zx_sils.seg(k).f();
00975 if ( !f && k > 0 )
00976 assert ( _zx_sils.seg(k-1).f() );
00977
00978
00979
00980 if (f) {
00981
00982 p = f->patch();
00983 assert(p);
00984
00985 p->zx_sils().add_seg (_zx_sils.seg(k));
00986
00987 if ( p != lp ) {
00988
00989
00990 if (!lp->zx_sils().segs().empty() && lp->zx_sils().segs().last().f()) {
00991
00992 lp->zx_sils().add_seg (
00993 NULL, _zx_sils.seg(k-1).p(), _zx_sils.seg(k-1).v(),
00994 _zx_sils.seg(k-1).g() , _zx_sils.seg(k-1).bc()
00995 );
00996 }
00997 }
00998 } else {
00999
01000 p = lp;
01001 p->zx_sils().add_seg (_zx_sils.seg(k));
01002
01003 }
01004 lp = p;
01005 }
01006
01007
01008 _zx_stamp = VIEW::stamp();
01009
01010 return _zx_sils.num();
01011 }
01012
01013 RunningAvg<double> rand_secs(0);
01014 RunningAvg<double> brute_secs(0);
01015 RunningAvg<double> zx_secs(0);
01016 RunningAvg<double> rand_sils(0);
01017 RunningAvg<double> brute_sils(0);
01018 RunningAvg<double> zx_sils(0);
01019 RunningAvg<double> all_edges(0);
01020
01021 int
01022 BMESH::get_zcross_strips()
01023 {
01024 static bool REALLY_HACK_EYE_POS = Config::get_var_bool("REALLY_HACK_EYE_POS",false);
01025 static bool HACK_EYE_POS = Config::get_var_bool("HACK_EYE_POS",false);
01026 static bool ALLOW_CHECK_ALL = Config::get_var_bool("ALLOW_CHECK_ALL",false);
01027 static int CHECK_ALL_UNDER = Config::get_var_int ("CHECK_ALL_UNDER", 1000, true);
01028
01029 ARRAY<ZXseg> old_segs = _zx_sils.segs();
01030
01031 _zx_sils.reset();
01032 if (HACK_EYE_POS && (geom()->has_transp() | REALLY_HACK_EYE_POS)) {
01033
01034
01035 Wpt light_pos;
01036 VIEWptr v = VIEW::peek();
01037 if (v->light_get_in_cam_space(3))
01038 light_pos = v->cam()->xform().inverse() *
01039 v->light_get_coordinates_p(3);
01040
01041 else
01042 light_pos = v->light_get_coordinates_p(3);
01043
01044 light_pos = inv_xform() * light_pos;
01045
01046 _zx_sils.set_eye(light_pos);
01047 } else
01048 _zx_sils.set_eye(eye_local());
01049
01050 int n = _faces.num();
01051 bool CHECK_ALL = ALLOW_CHECK_ALL && (_faces.num() < CHECK_ALL_UNDER);
01052 static int min_rand_faces = Config::get_var_int("RANDOMIZED_MIN_FACES", 4000, true);
01053 if (n < min_rand_faces ||
01054 _zx_stamp < VIEW::stamp() - 1 ||
01055 old_segs.empty() ||
01056 !_random_sils || CHECK_ALL) {
01057
01058
01059 for (int k = 0; k < n ; k++)
01060 _zx_sils.start_sil(_faces[k]);
01061
01062 } else {
01063 int k,i;
01064
01065
01066 stop_watch clock;
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076 CBedge_list& creases = get_creases();
01077 for (i=0; i<creases.num(); i++) {
01078 Bedge* e = creases[i];
01079 if (e && e->f(1))
01080 _zx_sils.start_sil(e->f(1));
01081 if (e && e->f(2))
01082 _zx_sils.start_sil(e->f(2));
01083 }
01084 CBedge_list& borders = get_borders();
01085 for (i=0; i<borders.num(); i++) {
01086 Bedge* e = borders[i];
01087 if (e && e->f(1))
01088 _zx_sils.start_sil(e->f(1));
01089 if (e && e->f(2))
01090 _zx_sils.start_sil(e->f(2));
01091 }
01092
01093
01094 for (k=0 ; k<old_segs.num(); k++) {
01095
01096 if (old_segs[k].f())
01097 _zx_sils.start_sil(old_segs[k].f());
01098 }
01099
01100
01101 int maxj = n - 1;
01102 for (k = (int)(2. * sqrt((double)n)); k>0; k--) {
01103
01104
01105 int j = min((int)(drand48()*n), maxj);
01106 _zx_sils.start_sil(_faces[j]);
01107 }
01108
01109
01110 zx_secs.add(clock.elapsed_time());
01111 zx_sils.add(_zx_sils.num());
01112 }
01113
01114 _zx_stamp = VIEW::stamp();
01115
01116 return _faces.num();
01117 }
01118
01119 int
01120 BMESH::build_sil_strips()
01121 {
01122
01123 if (_sil_stamp == VIEW::stamp() || _freeze_sils)
01124 return 0;
01125
01126
01127 int k;
01128 for (k = 0; k<_patches.num(); k++)
01129 _patches[k]->sils().reset();
01130
01131
01132 get_sil_strips();
01133
01134
01135 Patch* p;
01136 for (k = 0; k < _sils.num(); k++) {
01137 Bedge* e = _sils.edge(k);
01138 Bface* f = e->frontfacing_face();
01139
01140
01141 if (!f)
01142 f = e->get_face();
01143 if (f && (p = f->patch()))
01144 p->sils().add(_sils.vert(k), e);
01145 }
01146
01147
01148 _sil_stamp = VIEW::stamp();
01149
01150 return _sils.num();
01151 }
01152
01153 int
01154 BMESH::get_sil_strips()
01155 {
01156
01157 all_edges.add(nedges());
01158
01159
01160 Bedge_list old_sils = _sils.edges();
01161
01162
01163 _sils.reset();
01164
01165
01166 NewSilEdgeFilter filter(VIEW::stamp(), !show_secondary_faces());
01167
01168 static int min_rand_edges =
01169 Config::get_var_int("RANDOMIZED_MIN_EDGES", 4000, true);
01170
01171 if (nedges() < min_rand_edges ||
01172 _sil_stamp < VIEW::stamp() - 1 ||
01173 old_sils.empty() ||
01174 !_random_sils) {
01175
01176
01177 stop_watch clock;
01178
01179
01180 for (int k = 0; k < _edges.num(); k++)
01181 if (_edges[k]->is_sil())
01182 _sils.build(0, _edges[k], filter);
01183
01184
01185 brute_secs.add(clock.elapsed_time());
01186 brute_sils.add(_sils.num());
01187
01188 } else {
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200 stop_watch clock;
01201
01202
01203 int k;
01204 for (k = 0; k < old_sils.num(); k++)
01205 if (old_sils[k]->is_sil())
01206 _sils.build(0, old_sils[k], filter);
01207
01208
01209
01210
01211
01212 int n = _edges.num();
01213 k = (int)(2*sqrt((double)n));
01214 for (int maxj = n - 1; k>0; k--) {
01215
01216
01217 int j = min((int)(drand48()*n), maxj);
01218 if (_edges[j]->is_sil())
01219 _sils.build(0, _edges[j], filter);
01220 }
01221
01222
01223 rand_secs.add(clock.elapsed_time());
01224 rand_sils.add(_sils.num());
01225 }
01226
01227
01228 _sil_stamp = VIEW::stamp();
01229
01230 return _sils.num();
01231 }
01232
01233 EdgeStrip
01234 BMESH::sil_strip()
01235 {
01236
01237 build_sil_strips();
01238 return _sils;
01239 }
01240
01241 void
01242 BMESH::set_geom(GEOM *geom)
01243 {
01244 if (_geom)
01245 err_msg("BMESH::set_geom: warning: overwriting old geom");
01246 if (!geom)
01247 err_msg("BMESH::set_geom: warning: new geom is null");
01248 _geom = geom;
01249 }
01250
01251 CWtransf&
01252 BMESH::xform() const
01253 {
01254 ((BMESH*)this)->_obj_to_world = (_geom ? _geom->obj_to_world() : Identity);
01255 return _obj_to_world;
01256 }
01257
01258 CWtransf&
01259 BMESH::inv_xform() const
01260 {
01261 ((BMESH*)this)->_world_to_obj = (_geom ? _geom->world_to_obj() : Identity);
01262 return _world_to_obj;
01263 }
01264
01265 CWtransf&
01266 BMESH::obj_to_ndc() const
01267 {
01268 if (_pm_stamp != VIEW::stamp()) {
01269 ((BMESH*)this)->_pm_stamp = VIEW::stamp();
01270 ((BMESH*)this)->_pm = VIEW::peek_cam()->ndc_projection() * xform();
01271 }
01272 return _pm;
01273 }
01274
01275 CWpt&
01276 BMESH::eye_local() const
01277 {
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288 if (_eye_local_stamp != VIEW::stamp()) {
01289 ((BMESH*)this)->_eye_local_stamp = VIEW::stamp();
01290 CWpt& eye = VIEW::peek_cam()->data()->from();
01291 ((BMESH*)this)->_eye_local = inv_xform() * eye;
01292 }
01293 return _eye_local;
01294 }
01295
01296 void
01297 BMESH::make_patch_if_needed()
01298 {
01299 Patch* p = 0;
01300
01301 for (int k=0; k<_faces.num(); k++) {
01302 if (!bf(k)->patch()) {
01303 if (!p)
01304 p=new_patch();
01305 p->add
01306 (bf(k));
01307 }
01308 }
01309 }
01310
01311 bool
01312 BMESH::remove_patch(int k)
01313 {
01314 if (!_patches.valid_index(k)) {
01315 err_msg("BMESH::remove_patch: it's not in the list of patches");
01316 return 0;
01317 }
01318 Patch* p = _patches[k];
01319 if (p->num_faces() != 0)
01320 err_msg("BMESH::remove_patch: removed patch, %d faces left stranded",
01321 p->num_faces());
01322 _patches.remove(k);
01323 _drawables -= p;
01324 delete p;
01325 return 1;
01326 }
01327
01328 void
01329 BMESH::clean_patches()
01330 {
01331
01332
01333 bool debug = Config::get_var_bool("DEBUG_CLEAN_PATCHES",false);
01334
01335
01336 for (int i=_patches.num()-1; i>=0; i--)
01337 if (_patches[i]->num_faces() == 0)
01338 if (remove_patch(i) && debug)
01339 err_msg("BMESH::clean_patches: got one");
01340
01341 }
01342
01343
01344 void
01345 BMESH::send_update_notification()
01346 {
01347
01348 BMESHobs::broadcast_update_request(this);
01349
01350
01351 }
01352
01353 RefImageClient::ref_img_t
01354 BMESH::use_ref_image()
01355 {
01356 return (draw_enabled() ?
01357 _drawables.use_ref_image() : RefImageClient::REF_IMG_NONE);
01358 }
01359
01360 int
01361 BMESH::draw_vis_ref()
01362 {
01363 if (!draw_enabled())
01364 return 0;
01365
01366 send_update_notification();
01367
01368 return _drawables.draw_vis_ref();
01369 }
01370
01371 int
01372 BMESH::draw_ref_img(ref_img_t t)
01373 {
01374 if (!draw_enabled())
01375 return 0;
01376
01377 send_update_notification();
01378
01379 return _drawables.draw_ref_img(t);
01380 }
01381
01382 int
01383 BMESH::draw(CVIEWptr& v)
01384 {
01385 if (empty() || !draw_enabled())
01386 return 0;
01387
01388
01389
01390 send_update_notification();
01391
01392 if (empty()) {
01393 err_msg("BMESH::draw: warning: mesh is empty");
01394 return 0;
01395 }
01396
01397 int ret = _drawables.draw(v);
01398
01399 return ret;
01400 }
01401
01402 void
01403 BMESH::transform(CWtransf &xform, CMOD& m)
01404 {
01405 for (int k=nverts()-1; k>=0; k--)
01406 _verts[k]->transform(xform);
01407
01408
01409
01410 BMESHobs::broadcast_xform(this, xform, m);
01411
01412 changed(VERT_POSITIONS_CHANGED);
01413 }
01414
01415 CWpt_list &
01416 BMESH::vertices()
01417 {
01418 if (!_vert_locs.empty() || _verts.empty())
01419 return _vert_locs;
01420
01421 _vert_locs.realloc(nverts());
01422 for (int k=nverts()-1; k>=0; k--)
01423 _vert_locs += _verts[k]->loc();
01424 return _vert_locs;
01425 }
01426
01427 void
01428 BMESH::triangulate(Wpt_list &verts, FACElist &faces)
01429 {
01430 verts.clear();
01431 faces.clear();
01432 if (nverts() > 0)
01433 verts.realloc(_verts.num());
01434 if (nfaces() > 0)
01435 faces.realloc(_faces.num());
01436
01437 int i;
01438 for (i=0; i<nverts(); i++)
01439 verts += bv(i)->loc();
01440 for (i=0; i<nfaces(); i++)
01441 faces += Point3i(bf(i)->v(1)->index(),
01442 bf(i)->v(2)->index(),
01443 bf(i)->v(3)->index());
01444 }
01445
01446 BMESHptr
01447 BMESH::read_jot_file(char* filename, BMESHptr ret)
01448 {
01449
01450
01451 if (!filename) {
01452 err_msg("BMESH::read_jot_file() - Filename is NULL");
01453 return 0;
01454 }
01455 fstream fin;
01456 #if (defined (WIN32) && (defined(_MSC_VER) && (_MSC_VER <=1300)))
01457
01458 fin.open(filename, ios::in | ios::nocreate);
01459 #else
01460
01461 fin.open(filename, ios::in);
01462 #endif
01463
01464 if (!fin) {
01465 err_mesg(ERR_LEV_WARN, "BMESH::read_jot_file() - Could not open file '%s'", filename);
01466 return 0;
01467 }
01468
01469 return read_jot_stream(fin, ret);
01470 }
01471
01472 BMESHptr
01473 BMESH::read_jot_stream(istream& in, BMESHptr ret)
01474 {
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484 while (isspace(in.peek()))
01485 in.get();
01486
01487
01488 char firstchar = in.peek();
01489
01490 if (!isprint(firstchar)) {
01491 err_msg("BMESH::read_jot_stream() - Unreadable: Non-printable first character.");
01492 return 0;
01493 } else if (isdigit(firstchar)) {
01494
01495
01496 if (!ret) {
01497 ret = new LMESH;
01498 }
01499 if (ret->read_stream(in)) {
01500 return ret;
01501 } else {
01502 err_msg("BMESH::read_jot_stream() - Error: Failed parsing old-style file.");
01503 return 0;
01504 }
01505 } else if (firstchar == '#') {
01506
01507 char file_header[2048];
01508 in.get();
01509 in >> file_header;
01510
01511 err_mesg(ERR_LEV_INFO,
01512 "BMESH::read_jot_stream() - Warning: Rejecting file with '#%s' header.",
01513 file_header);
01514 return 0;
01515 } else {
01516
01517 STDdstream stream(&in);
01518
01519
01520 str_ptr class_name;
01521 stream >> class_name;
01522
01523
01524
01525 if (!(ret && ret->is_of_type(class_name))) {
01526 DATA_ITEM* di = DATA_ITEM::lookup(class_name);
01527 if (!di) {
01528 err_msg(
01529 "BMESH::read_jot_stream() - Error: Supposed mesh class '#%s' not found.",
01530 **class_name);
01531 return 0;
01532 }
01533
01534
01535 ret = upcast(di->dup());
01536 if (!ret) {
01537 err_msg(
01538 "BMESH::read_jot_stream() - Error: Class '#%s' is not a BMESH subclass.",
01539 **class_name);
01540 return 0;
01541 }
01542 }
01543
01544 ret->decode(stream);
01545 return ret;
01546 }
01547 }
01548
01549 bool
01550 BMESH::read_file(char* filename)
01551 {
01552
01553
01554 BMESHptr mesh = read_jot_file(filename, this);
01555 if (!mesh)
01556 return false;
01557
01558
01559
01560
01561 if (this != &*mesh)
01562 *this = *mesh;
01563
01564 return true;
01565 }
01566
01567
01568
01569 int
01570 BMESH::read_update_file(char* filename)
01571 {
01572 if (!filename) {
01573 err_ret( "BMESH::read_update_file: filename is NULL");
01574 return 0;
01575 }
01576
01577 ifstream fin;
01578 fin.open(filename);
01579 if (!fin) {
01580 err_ret( "BMESH::read_update_file: could not open file %s", filename);
01581 return 0;
01582 }
01583
01584 int ret = 1;
01585
01586 if (!read_update_stream(fin)) {
01587 err_msg("BMESH::read_update_file: error reading file %s", filename);
01588 ret = 0;
01589 }
01590
01591 return ret;
01592 }
01593
01594
01595 int
01596 BMESH::read_update_stream(istream& is)
01597 {
01598
01599 if (!read_header(is))
01600 return 0;
01601
01602
01603 int ret = read_vertices(is);
01604
01605 if (ret) {
01606
01607 changed(VERT_POSITIONS_CHANGED);
01608 }
01609
01610
01611 return ret;
01612 }
01613
01614
01615
01616 int
01617 BMESH::read_stream(istream& is)
01618 {
01619
01620 delete_elements();
01621
01622
01623 if (!read_header(is))
01624 return 0;
01625
01626
01627 int ret = read_vertices(is);
01628
01629
01630 ret = ret && read_faces(is);
01631
01632 if (!ret) {
01633
01634 changed(TOPOLOGY_CHANGED);
01635 make_patch_if_needed();
01636 return 0;
01637 }
01638
01639
01640
01641 read_creases(is);
01642
01643
01644
01645 read_polylines(is);
01646
01647
01648 changed(TOPOLOGY_CHANGED);
01649
01650
01651
01652 if (is_points() && Config::get_var_bool("BMESH_BUILD_VERT_STRIPS",false))
01653 build_vert_strips();
01654
01655
01656 ret = ret && read_blocks(is);
01657
01658
01659
01660 make_patch_if_needed();
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671 clean_patches();
01672
01673 return ret;
01674 }
01675
01676 int
01677 BMESH::read_blocks(istream &is)
01678 {
01679 if (Config::get_var_bool("JOT_SKIP_IOBLOCKS",false))
01680 return true;
01681
01682 static IOBlockList blocklist;
01683 if (blocklist.num() == 0) {
01684 blocklist += new IOBlockMeth<BMESH>("COLORS",
01685 &BMESH::read_colors, this);
01686 blocklist += new IOBlockMeth<BMESH>("TEX_COORDS2",
01687 &BMESH::read_texcoords2, this);
01688 blocklist += new IOBlockMeth<BMESH>("WEAK_EDGES",
01689 &BMESH::read_weak_edges, this);
01690 blocklist += new IOBlockMeth<BMESH>("PATCH",
01691 &BMESH::read_patch, this);
01692 blocklist += new IOBlockMeth<BMESH>("INCLUDE",
01693 &BMESH::read_include, this);
01694
01695 } else {
01696 for (int i = 0; i < blocklist.num(); i++) {
01697 ((IOBlockMeth<BMESH> *) blocklist[i])->set_obj(this);
01698 }
01699 }
01700 str_list leftover;
01701 int ret = IOBlock::consume(is, blocklist, leftover);
01702
01703 for (int w = 0; w < leftover.num(); w++) {
01704 str_ptr str = leftover[w];
01705 is.putback(' ');
01706 for (int i = str.len()-1; i >= 0; i--) {
01707 is.putback(str[i]);
01708 }
01709 }
01710
01711
01712 return ret;
01713 }
01714
01715 int
01716 BMESH::read_include(istream& is, str_list &)
01717 {
01718 const int len = 1024;
01719 char buff[len];
01720 is >> buff;
01721 ifstream fin;
01722 fin.open(buff);
01723 if (!fin) {
01724 err_ret( "BMESH::read_include: could not open include file %s", buff);
01725 return 0;
01726 }
01727 return read_blocks(fin);
01728 }
01729
01730 int
01731 BMESH::read_header(istream& is)
01732 {
01733 char file_header[256];
01734 char firstchar = is.peek();
01735
01736
01737 if (!isprint(firstchar))
01738 return 0;
01739
01740
01741 if (firstchar != '#')
01742 return 1;
01743
01744
01745 is.get();
01746 is >> file_header;
01747 if (is.bad() || is.eof())
01748 return 0;
01749
01750 if (strstr(file_header, "jot")) {
01751 err_msg("BMESH::read_header() - Trying to read a file with #jot header, stopping...");
01752 return 0;
01753 } else {
01754 err_msg("BMESH::read_header() - Reading a file with %s header...",file_header);
01755 return 1;
01756 }
01757
01758 }
01759
01760 int
01761 BMESH::read_vertices(istream& is)
01762 {
01763 int n;
01764 is >> n;
01765 if (is.bad() || is.eof()) {
01766 return 0;
01767 }
01768
01769 _verts.realloc(n);
01770 _edges.realloc(3*n);
01771
01772 for (int i=0 ; i<n; i++) {
01773 double x, y, z;
01774 is >> x >> y >> z;
01775
01776 if (i<_verts.num())
01777 _verts[i]->set_loc(Wpt(x,y,z));
01778 else
01779 add_vertex(Wpt(x,y,z));
01780 }
01781
01782 return 1;
01783 }
01784
01785 int
01786 BMESH::read_faces(istream& is)
01787 {
01788 int n = 0, i, j, k;
01789 is >> n;
01790 if (is.bad())
01791 return 0;
01792
01793 if (n>0)
01794 _faces.realloc(n);
01795
01796 int ret = 1;
01797
01798 for ( ; n>0 && !is.eof(); n--) {
01799
01800
01801 is >> i >> j >> k;
01802
01803
01804 if (!add_face(i,j,k,0))
01805 ret = 0;
01806 }
01807
01808 return ret;
01809 }
01810
01811 int
01812 BMESH::read_creases(istream& is)
01813 {
01814
01815
01816
01817 int n;
01818 is >> n;
01819
01820 int ret = 1;
01821 if (is.bad()) {
01822 err_ret( "BMESH::read_creases: istream is bad");
01823 return 0;
01824 }
01825 for (int k=0; k<n && !is.eof(); k++) {
01826 int i, j;
01827 is >> i >> j;
01828 if (!set_crease(i,j))
01829 ret = 0;
01830 }
01831
01832 return ret;
01833 }
01834
01835 int
01836 BMESH::read_weak_edges(istream& is, str_list &leftover)
01837 {
01838 leftover.clear();
01839
01840 if (is.bad()) {
01841 err_ret( "BMESH::read_weak_edges: istream is bad");
01842 return 0;
01843 }
01844
01845 int n, ret = 1;
01846 is >> n;
01847 for (int k=0; k<n && !is.eof(); k++) {
01848 int i, j;
01849 is >> i >> j;
01850 if (!set_weak_edge(i,j))
01851 ret = 0;
01852 }
01853
01854 return ret;
01855 }
01856
01857 int
01858 BMESH::read_polylines(istream& is)
01859 {
01860
01861
01862
01863 int n;
01864 is >> n;
01865
01866 int ret = 1;
01867 if (is.bad()) {
01868 err_ret( "BMESH::read_creases: istream is bad");
01869 ret = 0;
01870 } else {
01871 for (int k=0; k<n && !is.eof(); k++) {
01872 int i, j;
01873 is >> i >> j;
01874 if (!add_edge(i,j))
01875 ret = 0;
01876 }
01877 }
01878
01879 if (Config::get_var_bool("BMESH_BUILD_POLYSTRIPS",false) && n > 0)
01880 build_polyline_strips();
01881
01882 return ret;
01883 }
01884
01885 int
01886 BMESH::read_colors(istream& is, str_list &leftover)
01887 {
01888 leftover.clear();
01889 for (int i = 0; i< nverts(); i++) {
01890 double r,g,b;
01891 is >> r >> g >> b;
01892 bv(i)->set_color( COLOR(r,g,b));
01893 }
01894
01895 return 1;
01896 }
01897
01898
01899 int
01900 BMESH::read_texcoords2(istream& is, str_list &leftover)
01901 {
01902 static double UV_RESOLUTION = Config::get_var_dbl("UV_RESOLUTION",0,true);
01903
01904 leftover.clear();
01905 int n;
01906 is >> n;
01907 for (int i = 0; i<n; i++) {
01908 UVpt uv[3];
01909 int k;
01910 is >> k >> uv[0] >> uv[1] >> uv[2];
01911 if (_faces.valid_index(k)) {
01912
01913
01914 if (UV_RESOLUTION>0) {
01915 for (int j=0; j<3; j++) {
01916 double r;
01917 uv[j][0] -= r = fmod(uv[j][0],UV_RESOLUTION);
01918 if (2.0*fabs(r) > UV_RESOLUTION)
01919 uv[j][0] += ((r>0)?(UV_RESOLUTION):(-UV_RESOLUTION));
01920 uv[j][1] -= r = fmod(uv[j][1],UV_RESOLUTION);
01921 if (2.0*fabs(r) > UV_RESOLUTION)
01922 uv[j][1] += ((r>0)?(UV_RESOLUTION):(-UV_RESOLUTION));
01923 }
01924 }
01925
01926 UVdata::set
01927 (bf(k),uv[0], uv[1], uv[2]);
01928 } else
01929 err_msg("BMESH::read_texcoords2: invalid face index %d", k);
01930 }
01931
01932 return 1;
01933 }
01934
01935 int
01936 BMESH::read_patch(istream& is, str_list &leftover)
01937 {
01938 return new_patch()->read_stream(is, leftover);
01939 }
01940
01941 int
01942 BMESH::write_file(char* filename)
01943 {
01944 fstream fout;
01945 fout.open(filename, ios::out);
01946
01947 if (!fout) {
01948 err_msg("BMESH::write_file: error: could not open file: %s", filename);
01949 return 0;
01950 }
01951
01952 STDdstream stream(&fout);
01953 format(stream);
01954 fout.close();
01955
01956 return 1;
01957 }
01958
01959 int
01960 BMESH::write_stream(ostream& os)
01961 {
01962
01963
01964 STDdstream out(&os);
01965 format(out);
01966 os << endl;
01967
01968 return 1;
01969 }
01970
01971 int
01972 BMESH::write_vertices(ostream& os) const
01973 {
01974 os << nverts() << endl;
01975 if (os.bad())
01976 return 0;
01977
01978 bool xform_mesh = Config::get_var_bool("JOT_SAVE_XFORMED_MESH",false);
01979
01980 Wpt p;
01981 for (int i = 0; i< nverts(); i++) {
01982 if (xform_mesh)
01983 p = bv(i)->wloc();
01984 else
01985 p = bv(i)->loc();
01986 os << p[0] << " " << p[1] << " " << p[2] << endl;
01987 }
01988
01989 return 1;
01990 }
01991
01992 int
01993 BMESH::write_colors(ostream& os) const
01994 {
01995
01996
01997 if (!_verts.empty() && bv(0)->has_color()) {
01998
01999 if (os.bad())
02000 return 0;
02001
02002 os << "#BEGIN COLORS" << endl;
02003 for (int i = 0; i< nverts(); i++) {
02004 const COLOR& c = bv(i)->color();
02005 os << c[0] << " "
02006 << c[1] << " "
02007 << c[2] << " " << endl;
02008 }
02009 os << "#END COLORS" << endl;
02010 }
02011
02012 return 1;
02013 }
02014
02015 int
02016 BMESH::write_texcoords2(ostream& os) const
02017 {
02018
02019
02020
02021 if (os.bad())
02022 return 0;
02023
02024
02025 int count=0, k;
02026 for (k=0; k<nfaces(); k++)
02027 if (UVdata::lookup(bf(k)))
02028 count++;
02029
02030
02031 if (count == 0)
02032 return 1;
02033
02034
02035 os << "#BEGIN TEX_COORDS2" << endl;
02036 os << count << endl;
02037 for (k=0; k<nfaces(); k++) {
02038 UVdata* uvdata = UVdata::lookup(bf(k));
02039 if (uvdata) {
02040 os << k << " "
02041 << uvdata->uv(1) << " "
02042 << uvdata->uv(2) << " "
02043 << uvdata->uv(3) << endl;
02044 }
02045 }
02046 os << "#END TEX_COORDS2" << endl;
02047
02048 return 1;
02049 }
02050
02051 int
02052 BMESH::write_faces(ostream& os) const
02053 {
02054 os << nfaces() << endl;
02055 if (os.bad())
02056 return 0;
02057
02058 for (int i = 0; i< nfaces(); i++)
02059 os << *bf(i);
02060
02061 return 1;
02062 }
02063
02064 int
02065 BMESH::write_creases(ostream& os) const
02066 {
02067 if (nedges()<1 || os.bad())
02068 return 0;
02069
02070 static ARRAY<Bedge*> creases(512);
02071
02072 creases.clear();
02073
02074 int k;
02075 for (k=0; k<nedges(); k++)
02076 if (be(k)->is_crease())
02077 creases += be(k);
02078
02079 os << creases.num() << endl;
02080 while (!creases.empty())
02081 os << *creases.pop() << endl;
02082
02083 os << endl;
02084
02085 return 1;
02086 }
02087
02088 int
02089 BMESH::write_weak_edges(ostream& os) const
02090 {
02091 if (os.bad())
02092 return 0;
02093
02094 ARRAY<Bedge*> weak_edges(nedges());
02095
02096 for (int k=0; k<nedges(); k++)
02097 if (be(k)->is_weak())
02098 weak_edges += be(k);
02099
02100 if (!weak_edges.empty()) {
02101
02102 os << "#BEGIN WEAK_EDGES" << endl;
02103 os << weak_edges.num() << endl;
02104 while (!weak_edges.empty())
02105 os << *weak_edges.pop() << endl;
02106 os << endl;
02107
02108 os << "#END WEAK_EDGES" << endl;
02109 }
02110
02111 return 1;
02112 }
02113
02114 int
02115 BMESH::write_patches(ostream& os) const
02116 {
02117 if (_patches.empty() || Config::get_var_bool("TMOD_DONT_WRITE_PATCHES",false))
02118 return 1;
02119
02120
02121 if (_patches[0]->cur_tex()) {
02122 if (os.bad())
02123 return 0;
02124
02125 _patches.write_stream(os);
02126 }
02127 return 1;
02128 }
02129
02130 int
02131 BMESH::write_polylines(ostream& os) const
02132 {
02133 if (nedges()<1 || os.bad())
02134 return 0;
02135
02136
02137 static ARRAY<Bedge*> polylines(256);
02138
02139 polylines.clear();
02140
02141 int k;
02142 for (k=0; k<nedges(); k++)
02143 if (be(k)->is_polyline())
02144 polylines += be(k);
02145
02146 os << polylines.num() << endl;
02147 while (!polylines.empty())
02148 os << *polylines.pop() << endl;
02149
02150 os << endl;
02151
02152 return 1;
02153 }
02154
02155 void
02156 BMESH::delete_elements()
02157 {
02158 _drawables.clear();
02159
02160 _patches.delete_all();
02161
02162
02163
02164
02165 _faces.delete_all();
02166 _edges.delete_all();
02167 _verts.delete_all();
02168
02169 _type = EMPTY_MESH;
02170 _type_valid = 1;
02171 }
02172
02173 BMESH&
02174 BMESH::operator =(CBMESH& m)
02175 {
02176 delete_elements();
02177
02178 _type = m._type;
02179 _type_valid = m._type_valid;
02180
02181 if (m.nverts() > 0)
02182 _verts.realloc(m._verts.num());
02183 if (m.nedges() > 0)
02184 _edges.realloc(m._edges.num());
02185 if (m.nfaces() > 0)
02186 _faces.realloc(m._faces.num());
02187
02188
02189 int k;
02190 for (k=0; k<m.nverts(); k++) {
02191 Bvert* v_old = m.bv(k);
02192 Bvert* v_new = add_vertex(v_old->loc());
02193 if (v_old->has_color())
02194 v_new->set_color(v_old->color());
02195 }
02196
02197
02198 for (k=0; k<m.nedges(); k++) {
02199 Bedge* e_old = m.be(k);
02200 Bedge* e_new = add_edge(e_old->v1()->index(), e_old->v2()->index());
02201 if (e_old->is_crease())
02202 e_new->set_crease(e_old->crease_val());
02203 if (e_old->is_patch_boundary())
02204 e_new->set_patch_boundary();
02205 if (e_old->is_weak())
02206 e_new->set_bit(Bedge::WEAK_BIT);
02207 }
02208
02209
02210 Patch* p = new_patch();
02211
02212
02213 for (k=0; k<m.nfaces(); k++) {
02214 Bface* f_old = m.bf(k);
02215 Bface* f_new = add_face(f_old->v1()->index(),
02216 f_old->v2()->index(),
02217 f_old->v3()->index(), p);
02218 if (f_old->is_secondary())
02219 f_new->make_secondary();
02220 }
02221
02222 changed(TRIANGULATION_CHANGED);
02223
02224 return *this;
02225 }
02226
02227 BMESH&
02228 BMESH::operator =(BODY& body)
02229 {
02230 if (body.is_of_type(static_name()))
02231 return *this = *((BMESH*)&body);
02232
02233 delete_elements();
02234
02235 Wpt_list pts;
02236 FACElist tris;
02237 body.triangulate(pts, tris);
02238 if (pts.num() && tris.num()) {
02239 _verts.realloc(pts.num());
02240 _faces.realloc(tris.num());
02241 _edges.realloc(tris.num()*3/2+10);
02242 int i;
02243 for (i = 0; i < pts.num(); i++)
02244 add_vertex(pts[i]);
02245 Patch* p = new_patch();
02246 for (i = 0; i < tris.num(); i++)
02247 add_face(tris[i][0], tris[i][1], tris[i][2], p);
02248
02249
02250 changed(TOPOLOGY_CHANGED);
02251
02252
02253 if (!Config::get_var_bool("SUPPRESS_CREASES",false)) {
02254 for (int k= nedges()-1; k>=0; k--)
02255 be(k)->compute_crease(0.5);
02256 }
02257 }
02258
02259 return *this;
02260 }
02261
02262
02263 void
02264 BMESH::delete_patches()
02265 {
02266 _patches.delete_all();
02267 }
02268
02269 int
02270 BMESH::check_type()
02271 {
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283 _type_valid = 1;
02284 _type = EMPTY_MESH;
02285
02286
02287 int num_isolated_verts = 0,
02288 num_isolated_edges = 0,
02289 num_border_edges = 0,
02290 num_inconsistent_edges = 0;
02291
02292
02293 int k;
02294 for (k=0; k<_verts.num(); k++)
02295 if (bv(k)->degree() == 0)
02296 num_isolated_verts++;
02297
02298 if (num_isolated_verts > 0)
02299 _type |= POINTS;
02300
02301
02302
02303 for (k=0; k<_edges.num(); k++) {
02304 if (be(k)->nfaces() == 0)
02305 num_isolated_edges++;
02306 else if (be(k)->nfaces() == 1)
02307 num_border_edges++;
02308 else if (!be(k)->consistent_orientation())
02309 num_inconsistent_edges++;
02310 }
02311
02312
02313 if (num_isolated_edges > 0)
02314 _type |= POLYLINES;
02315
02316
02317
02318 if (num_border_edges > 0)
02319 _type |= OPEN_SURFACE;
02320 else if (nfaces() > 0)
02321 _type |= CLOSED_SURFACE;
02322
02323
02324 for (k=0; k<nfaces(); k++)
02325 _faces[k]->orient_strip(0);
02326
02327
02328 if (num_inconsistent_edges > 0) {
02329 err_msg("BMESH::check_type: inconsistently oriented faces found...");
02330 if (Config::get_var_bool("NO_FIX_ORIENTATION",false)) {
02331 err_msg("...leaving it as is");
02332 } else {
02333 if (fix_orientation())
02334 err_msg("fixed it");
02335 else
02336 err_msg("can't fix it");
02337 }
02338 }
02339
02340 return _type;
02341 }
02342
02343 bool
02344 BMESH::fix_orientation()
02345 {
02346 if (Config::get_var_bool("NO_FIX_ORIENTATION",false))
02347 return false;
02348
02349 bool debug = Config::get_var_bool("DEBUG_FIX_ORIENTATION",false);
02350
02351 _faces.clear_flags();
02352
02353 ARRAY<Bface*> pos_faces;
02354 ARRAY<Bface*> neg_faces;
02355 for (int k=0; k<_faces.num(); k++) {
02356 if (!_faces[k]->flag()) {
02357 if (debug)
02358 err_msg("fix_orientation: starting on untouched face...");
02359 pos_faces.clear();
02360 neg_faces.clear();
02361 _faces[k]->set_flag(1);
02362 pos_faces += _faces[k];
02363 grow_oriented_face_lists(_faces[k], pos_faces, neg_faces);
02364 reverse_faces((pos_faces.num() < neg_faces.num()) ?
02365 pos_faces : neg_faces);
02366 }
02367 }
02368 changed(TRIANGULATION_CHANGED);
02369
02370
02371 int num_inconsistent_edges = 0;
02372 for (int j=0; j<_edges.num(); j++)
02373 if (!_edges[j]->consistent_orientation())
02374 num_inconsistent_edges++;
02375
02376 if (num_inconsistent_edges > 0)
02377 err_msg("BMESH::fix_orientation: still found %d inconsistent edges!",
02378 num_inconsistent_edges);
02379
02380 return (num_inconsistent_edges == 0);
02381 }
02382
02383 void
02384 BMESH::grow_oriented_face_lists(
02385 Bface* f,
02386 ARRAY<Bface*>& pos_faces,
02387 ARRAY<Bface*>& neg_faces)
02388 {
02389 for (int i=1; i<=3; i++) {
02390 Bface* nbr = f->nbr(i);
02391 if (nbr && !nbr->flag()) {
02392 nbr->set_flag(1);
02393 if (f->e(i)->consistent_orientation()) {
02394 pos_faces += nbr;
02395 grow_oriented_face_lists(nbr, pos_faces, neg_faces);
02396 } else {
02397 neg_faces += nbr;
02398 grow_oriented_face_lists(nbr, neg_faces, pos_faces);
02399 }
02400 }
02401 }
02402 }
02403
02404 Bedge*
02405 BMESH::nearest_edge(CWpt &p)
02406 {
02407 if (_edges.empty())
02408 return 0;
02409
02410 Wpt q;
02411 Bedge *ret = _edges[0];
02412 double dist = (p - _edges[0]->project_to_simplex(p, q)).length_sqrd(), d;
02413
02414 for (int i=1; i<_edges.num(); i++) {
02415 if ((d = (p - _edges[i]->project_to_simplex(p, q)).length_sqrd()) < dist) {
02416 ret = _edges[i];
02417 dist = d;
02418 }
02419 }
02420
02421 return ret;
02422 }
02423
02424 Bvert*
02425 BMESH::nearest_vert(CWpt &p)
02426 {
02427 if (_verts.empty())
02428 return 0;
02429
02430 Bvert *ret = _verts[0];
02431 double dist = (p - _verts[0]->loc()).length_sqrd(), d;
02432
02433 for (int i=1; i<_verts.num(); i++) {
02434 if ((d = (p - _verts[i]->loc()).length_sqrd()) < dist) {
02435 ret = _verts[i];
02436 dist = d;
02437 }
02438 }
02439
02440 return ret;
02441 }
02442
02443 void
02444 BMESH::get_enclosed_verts(
02445 CXYpt_list& boundary,
02446 Bface* startface,
02447 ARRAY<Bvert*>& ret)
02448 {
02449
02450
02451
02452
02453
02454 ret.clear();
02455
02456
02457 if (startface->mesh() != this) {
02458 err_msg("BMESH::get_enclosed_verts: startface is from wrong mesh");
02459 return;
02460 }
02461
02462
02463 for (int j=0; j<nverts(); j++)
02464 bv(j)->clear_flag();
02465
02466 ARRAY<Bvert*> frontier;
02467
02468
02469
02470
02471 if (startface->v1()->ndc().in_frustum())
02472 frontier += startface->v1();
02473 if (startface->v2()->ndc().in_frustum())
02474 frontier += startface->v2();
02475 if (startface->v3()->ndc().in_frustum())
02476 frontier += startface->v3();
02477
02478 while (!frontier.empty()) {
02479 Bvert* v = frontier.pop();
02480
02481
02482
02483 XYpt xy = NDCpt(v->ndc());
02484
02485 if (boundary.contains(xy)) {
02486 ret += v;
02487 for (int i=0 ;i<v->degree(); i++) {
02488 Bvert *nbr = v->nbr(i);
02489 if (!nbr->flag()) {
02490 nbr->set_flag();
02491 frontier += nbr;
02492 }
02493 }
02494 }
02495 }
02496 }
02497
02498 int
02499 BMESH::remove_face(Bface* f)
02500 {
02501 _faces -= f;
02502 delete_face(f);
02503
02504 return 1;
02505 }
02506
02507 int
02508 BMESH::remove_edge(Bedge* e)
02509 {
02510 _edges -= e;
02511 delete_edge(e);
02512
02513 return 1;
02514 }
02515
02516 int
02517 BMESH::remove_vertex(Bvert* v)
02518 {
02519 _verts -= v;
02520 delete_vert(v);
02521
02522 return 1;
02523 }
02524
02525 int
02526 BMESH::remove_faces(CBface_list& faces)
02527 {
02528 if (!faces.empty() && faces.mesh() != this) {
02529 cerr <<"BMESH::remove_faces(): ERROR, faces not all from this mesh"
02530 << endl;
02531 return 0;
02532 }
02533
02534 for (int i=0; i<faces.num(); i++) {
02535 remove_face(faces[i]);
02536 }
02537
02538 return 1;
02539 }
02540
02541 int
02542 BMESH::remove_edges(CBedge_list& edges)
02543 {
02544 if (!edges.empty() && edges.mesh() != this) {
02545 cerr <<"BMESH::remove_edges(): ERROR, edges not all from this mesh"
02546 << endl;
02547 return 0;
02548 }
02549
02550 for (int i=0; i<edges.num(); i++) {
02551 remove_edge(edges[i]);
02552 }
02553
02554 return 1;
02555 }
02556
02557 int
02558 BMESH::remove_verts(CBvert_list& verts)
02559 {
02560 if (!verts.empty() && verts.mesh() != this) {
02561 cerr <<"BMESH::remove_verts(): ERROR, verts not all from this mesh"
02562 << endl;
02563 return 0;
02564 }
02565
02566 for (int i=0; i<verts.num(); i++) {
02567 remove_vertex(verts[i]);
02568 }
02569
02570 return 1;
02571 }
02572
02573 void
02574 BMESH::merge_vertex(Bvert* v, Bvert* u, bool keep_vert)
02575 {
02576
02577
02578
02579
02580
02581 Bface_list star_faces(6);
02582 v->get_all_faces(star_faces);
02583 int k;
02584 for (k=0; k<star_faces.num(); k++)
02585 star_faces[k]->detach();
02586
02587
02588
02589
02590 ARRAY<Bedge*> star_edges = v->get_adj();
02591 for (k=0; k<star_edges.num(); k++)
02592 if (!star_edges[k]->redefine(v,u))
02593 remove_edge(star_edges[k]);
02594
02595 for (k=0; k<star_faces.num(); k++)
02596 if (!star_faces[k]->redefine(v,u))
02597 remove_face(star_faces[k]);
02598
02599
02600 if (!keep_vert)
02601 remove_vertex(v);
02602 }
02603
02604
02605 int
02606 compare_locs_lexicographically(const void* va, const void* vb)
02607 {
02608
02609
02610 CWpt& a = (*((Bvert**)va))->loc();
02611 CWpt& b = (*((Bvert**)vb))->loc();
02612
02613 return ((a[0] > b[0]) ? 1 :
02614 (a[0] < b[0]) ? -1 :
02615 (a[1] > b[1]) ? 1 :
02616 (a[1] < b[1]) ? -1 :
02617 (a[2] > b[2]) ? 1 :
02618 (a[2] < b[2]) ? -1 :
02619 0);
02620 }
02621
02622 void
02623 BMESH::remove_duplicate_vertices(bool keep_verts)
02624 {
02625
02626
02627
02628 for (int j=nedges()-1; j>=0; j--) {
02629 if (_edges[j]->length() == 0)
02630 remove_edge(_edges[j]);
02631 }
02632
02633
02634
02635
02636
02637
02638
02639 Bvert_list verts = _verts;
02640
02641
02642 verts.sort(compare_locs_lexicographically);
02643
02644
02645
02646 int count = 0;
02647 Bvert* prev = verts[0];
02648 for (int k=1; k<verts.num(); k++) {
02649 if (verts[k]->loc() == prev->loc()) {
02650 merge_vertex(verts[k], prev, keep_verts);
02651 count++;
02652 } else
02653 prev = verts[k];
02654 }
02655
02656 if (count > 0) {
02657
02658 changed(TRIANGULATION_CHANGED);
02659
02660
02661
02662
02663
02664 int fixed = fix_orientation()
02665 ;
02666
02667
02668 err_msg("BMESH::remove_duplicate_vertices:");
02669 err_msg(" removed %d verts", count);
02670 err_msg(" %s orientation", fixed ? "fixed" : "warning: can't fix")
02671 ;
02672 }
02673 }
02674
02675
02676 Bvert*
02677 BMESH::split_edge(Bedge* edge, CWpt &p)
02678 {
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690 Bface* f1 = ccw_face(edge);
02691 Bface* f2 = edge->other_face(f1);
02692
02693 Bvert* a = edge->v1();
02694 Bvert* c = edge->v2();
02695
02696
02697 UVdata* uvd1 = UVdata::lookup(f1);
02698 UVdata* uvd2 = UVdata::lookup(f2);
02699
02700 UVpt uv1a, uv1c, uv1d;
02701 UVpt uv2a, uv2b, uv2c;
02702
02703 if (uvd1) {
02704 uv1a = uvd1->uv(a);
02705 uv1c = uvd1->uv(c);
02706 uv1d = uvd1->uv(f1->other_vertex(a,c));
02707 }
02708 if (uvd2) {
02709 uv2a = uvd2->uv(a);
02710 uv2b = uvd2->uv(f2->other_vertex(a,c));
02711 uv2c = uvd2->uv(c);
02712 }
02713
02714
02715 if (f1)
02716 f1->detach();
02717 if (f2)
02718 f2->detach();
02719
02720
02721 Bvert* v = add_vertex(p);
02722
02723
02724
02725 edge->notify_split(v);
02726
02727
02728 edge->redefine(a,v);
02729
02730
02731 Bedge* av = add_edge(v,a);
02732
02733
02734
02735 edge->notify_split(av);
02736
02737 if (f1) {
02738 Bvert* d = f1->other_vertex(a,c);
02739
02740
02741
02742 f1->notify_split(add_edge(v,d));
02743
02744
02745 f1->redefine(a,v);
02746
02747
02748 Bface* avd = add_face(v,d,a,f1->patch());
02749
02750
02751 f1->notify_split(avd);
02752
02753 if (uvd1) {
02754 UVpt uv1v = (uv1a + uv1c)/2;
02755 UVdata::set
02756 (f1, v, c, d, uv1v, uv1c, uv1d);
02757 UVdata::set
02758 (avd, v, d, a, uv1v, uv1d, uv1a);
02759 }
02760 }
02761 if (f2) {
02762 Bvert* b = f2->other_vertex(a,c);
02763 f2->notify_split(add_edge(v,b));
02764 f2->redefine(a,v);
02765 Bface* abv = add_face(v,a,b,f2->patch());
02766 f2->notify_split(abv);
02767
02768 if (uvd2) {
02769 UVpt uv2v = (uv2a + uv2c)/2;
02770 UVdata::set
02771 (f2, v, b, c, uv2v, uv2b, uv2c);
02772 UVdata::set
02773 (abv, v, a, b, uv2v, uv2a, uv2b);
02774 }
02775 }
02776
02777 return v;
02778 }
02779
02780 Bvert*
02781 BMESH::split_face(Bface *face, CWpt &pos)
02782 {
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797 Bvert* a = face->v1();
02798 Bvert* b = face->v2();
02799 Bvert* c = face->v3();
02800
02801
02802 UVpt uva, uvb, uvc, uvp;
02803 UVdata* uvd = UVdata::lookup(face);
02804 if (face) {
02805 uva = uvd->uv1();
02806 uvb = uvd->uv2();
02807 uvc = uvd->uv3();
02808 Wvec bc;
02809 face->project_barycentric(pos, bc);
02810 uvd->bc2uv(bc, uvp);
02811 }
02812 face->detach();
02813
02814 Bvert *v = add_vertex(pos);
02815 Bedge *av = add_edge(a,v);
02816 Bedge *bv = add_edge(b,v);
02817 Bedge *cv = add_edge(c,v);
02818
02819 face->redefine(c,v);
02820
02821 Bface *bcv = add_face(b,c,v,face->patch());
02822 Bface *cav = add_face(c,a,v,face->patch());
02823
02824 if (uvd) {
02825 UVdata::set
02826 (face, uva, uvb, uvp);
02827 UVdata::set
02828 (bcv, uvb, uvc, uvp);
02829 UVdata::set
02830 (cav, uvc, uva, uvp);
02831 }
02832 face->notify_split(v);
02833 face->notify_split(av);
02834 face->notify_split(bv);
02835 face->notify_split(cv);
02836 face->notify_split(bcv);
02837 face->notify_split(cav);
02838
02839 return v;
02840 }
02841
02842
02843 int
02844 BMESH::split_faces(
02845 CXYpt_list &pts,
02846 ARRAY<Bvert *> &verts,
02847 Bface* start_face)
02848 {
02849
02850
02851
02852
02853
02854
02855 int closed = pts.num() > 2 && pts[0] == pts.last();
02856
02857 cerr << (closed? " It's closed " : "Open!")<<endl;
02858 verts.clear();
02859
02860 if (pts.empty()) {
02861 return 0;
02862 }
02863
02864 Bface* cur=0;
02865 Wpt cur_pt;
02866 if (!start_face) {
02867 BaseVisRefImage *vis_ref = BaseVisRefImage::lookup(VIEW::peek());
02868 if (!vis_ref) {
02869 err_msg("BMESH::split_faces: error: can't get BaseVisRefImage");
02870 return 0;
02871 }
02872 vis_ref->vis_update();
02873 cur = vis_ref->vis_intersect(pts[0], cur_pt);
02874 } else {
02875 cur = start_face;
02876 cur_pt = cur->plane_intersect(inv_xform() * Wline(pts[0]));
02877 }
02878
02879 if (!cur || cur->mesh() != this) {
02880 return 0;
02881 }
02882
02883 verts += split_face(cur, cur_pt);
02884 NDCpt new_ndc;
02885
02886 Bface_list star_faces(16);
02887
02888 for (int i=1; i < pts.num(); ) {
02889
02890
02891
02892 int success = 0;
02893 verts.last()->get_faces(star_faces);
02894 NDCpt last_ndc = xform() * verts.last()->loc();
02895
02896 if (closed && i==pts.num()-1) {
02897 cerr << "In closed search" <<endl;
02898
02899
02900 for (int j=0; j < verts.last()->degree(); j++) {
02901 if (verts.last()->nbr(j) == verts[0]) {
02902 i++;
02903 success = 1;
02904 Bvert* v= verts[0];
02905 verts += v;
02906 break;
02907 }
02908 }
02909 if (!success)
02910 cerr << "BMESH::split_faces: Closed SearchFailed" << endl;
02911 else {
02912 cerr << "BMESH::split_faces: Closing correctly" << endl;
02913 assert(verts[0]==verts.last());
02914 }
02915 }
02916
02917
02918
02919
02920 if (!success) {
02921 for (int j=0; j<star_faces.num(); j++) {
02922
02923 if (star_faces[j]->ndc_contains(pts[i]) ) {
02924
02925 if (i==pts.num()-1)
02926 cerr << "BMESH::split_faces: Why here" << endl;
02927 Wpt new_pt = star_faces[j]->plane_intersect(
02928 inv_xform() * Wline(pts[i]));
02929 verts += split_face(star_faces[j], new_pt);
02930 cerr << "BMESH::split_faces: Split face insert "
02931 << verts.num()
02932 << endl;
02933 i++;
02934
02935 success = 1;
02936 break;
02937 } else if (star_faces[j]->opposite_edge(verts.last())->
02938 ndc_intersect(last_ndc, pts[i], new_ndc)) {
02939
02940 if (i==pts.num()-1)
02941 cerr << "Kept going" << endl;
02942 Wpt new_pt = star_faces[j]->plane_intersect(
02943 inv_xform() * Wline(new_ndc));
02944 verts += split_edge(
02945 star_faces[j]->opposite_edge(verts.last()),new_pt);
02946
02947 cerr << "BMESH::split_faces: Split edge insert "
02948 << verts.num()
02949 << endl;
02950 success = 1;
02951 break;
02952 }
02953 }
02954 }
02955
02956 if (!success) {
02957 cerr << "i fail " << i << endl;
02958 cerr << "pts.num() " << pts.num() <<endl;
02959 return 0;
02960 }
02961 }
02962
02963 cerr << "BMESH::Split_faces :: Success.. returning "
02964 << verts.num()
02965 << " vertices"
02966 << endl;
02967 changed(TRIANGULATION_CHANGED);
02968 return 1;
02969 }
02970
02971 int
02972 BMESH::try_swap_edge(Bedge* edge, bool favor)
02973 {
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996 Bface *f1=0, *f2=0;
02997 Bvert *a=0, *b=0, *c=0, *d=0;
02998 if (!edge->swapable(f1,f2,a,b,c,d, favor))
02999 return 0;
03000
03001
03002 f1->detach();
03003 f2->detach();
03004
03005
03006 edge->set_new_vertices(d,b);
03007
03008 f1->redefine(a,b);
03009 f2->redefine(c,d);
03010
03011 return 1;
03012 }
03013
03014 int
03015 BMESH::try_collapse_edge(Bedge* e, Bvert* v)
03016 {
03017
03018
03019 Bvert *u = 0;
03020
03021 if (v) {
03022
03023 u = e->other_vertex(v);
03024 assert(u);
03025 } else {
03026
03027 v = e->v(1);
03028 u = e->v(2);
03029 }
03030
03031
03032
03033
03034
03035
03036
03037
03038 if (nverts()<5)
03039 return 0;
03040
03041
03042 static bool debug = Config::get_var_bool("SKIN_DEBUG",false);
03043 if (v->is_border() && u->is_border() && !e->is_border()) {
03044 if (debug)
03045 cerr << "BMESH::try_collapse_edge: Case 2 failure" <<endl;
03046 return 0;
03047 }
03048
03049
03050 if (e->f1() || e->f2()) {
03051 Bvert* op1 = e->opposite_vert1();
03052 Bvert* op2 = e->opposite_vert2();
03053 for (int k=v->degree()-1; k>=0; k--) {
03054 Bvert* vnbr = v->nbr(k);
03055 if (vnbr != u && u->is_adjacent(vnbr) && vnbr != op1 && vnbr != op2) {
03056 if (debug)
03057 cerr << "BMESH::try_collapse_edge: Case 3 failure" <<endl;
03058 return 0;
03059 }
03060 }
03061 }
03062
03063
03064 merge_vertex(v, u);
03065
03066 return 1;
03067 }
03068
03069
03070 Patch*
03071 BMESH::new_patch()
03072 {
03073 _patches += new Patch(this);
03074 if (subdiv_level() == 0)
03075 _drawables += _patches.last();
03076
03077 return _patches.last();
03078 }
03079
03080 bool
03081 BMESH::unlist(Patch* p)
03082 {
03083
03084
03085 if (!(p && p->mesh() && p->mesh() == this))
03086 return false;
03087 return _patches -= p;
03088 }
03089
03090 void
03091 BMESH::changed(change_t change)
03092 {
03093 REFlock lock((REFcounter *)this)
03094 ;
03095
03096 if (change == NO_CHANGE)
03097 return;
03098
03099 if (change == PATCHES_CHANGED) {
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109 _sil_stamp = 0;
03110 _zx_stamp = 0;
03111
03112 }
03113
03114 switch (change) {
03115
03116
03117 case TOPOLOGY_CHANGED:
03118
03119 _type_valid = 0;
03120
03121 case TRIANGULATION_CHANGED:
03122
03123
03124 _sil_stamp = 0;
03125 _sils.reset();
03126
03127
03128 _zx_sils.reset();
03129 _zx_stamp = 0;
03130
03131
03132 delete _borders;
03133 _borders = 0;
03134
03135
03136 delete _creases;
03137 _creases = 0;
03138
03139 _patches.triangulation_changed();
03140
03141 case VERT_POSITIONS_CHANGED:
03142
03143
03144
03145
03146
03147 _zx_stamp = 0;
03148
03149
03150 _vert_locs.clear();
03151 BODY::_edges.reset();
03152 _body = BODYptr(0);
03153 _bb.reset();
03154 _avg_edge_len_valid = 0;
03155
03156
03157 delete _curv_data;
03158 _curv_data = 0;
03159
03160 break;
03161
03162 case CREASES_CHANGED:
03163
03164 _patches.creases_changed();
03165 delete _creases;
03166 _creases = 0;
03167
03168 default:
03169 ;
03170 }
03171
03172 BMESHobs::broadcast_change(this, change);
03173
03174
03175 _version++;
03176 }
03177
03178 const BBOX &
03179 BMESH::get_bb()
03180 {
03181 if (_bb.valid())
03182 return _bb;
03183
03184 for (int i = 0; i< nverts(); i++) {
03185 _bb.update(bv(i)->loc());
03186 }
03187 return _bb;
03188 }
03189
03190 CTAGlist &
03191 BMESH::tags() const
03192 {
03193
03194
03195 if ( (IOManager::state() == IOManager::STATE_PARTIAL_LOAD) ||
03196 (IOManager::state() == IOManager::STATE_PARTIAL_SAVE) ) {
03197 if (!_bmesh_update_tags) {
03198 _bmesh_update_tags = new TAGlist;
03199
03200 *_bmesh_update_tags += BODY::tags();
03201
03202 *_bmesh_update_tags += new TAG_meth<BMESH>(
03203 "vertices", &BMESH::put_vertices, &BMESH::get_vertices, 1
03204 );
03205 }
03206 return *_bmesh_update_tags;
03207 }
03208
03209
03210 if (!_bmesh_tags) {
03211
03212 _bmesh_tags = new TAGlist;
03213
03214 *_bmesh_tags += BODY::tags();
03215
03216
03217
03218 *_bmesh_tags += new TAG_meth<BMESH>(
03219 "vertices", &BMESH::put_vertices, &BMESH::get_vertices, 1
03220 );
03221 *_bmesh_tags += new TAG_meth<BMESH>(
03222 "faces", &BMESH::put_faces, &BMESH::get_faces, 1
03223 );
03224 *_bmesh_tags += new TAG_meth<BMESH>(
03225 "uvfaces", &BMESH::put_uvfaces, &BMESH::get_uvfaces, 1
03226 );
03227 *_bmesh_tags += new TAG_meth<BMESH>(
03228 "creases", &BMESH::put_creases, &BMESH::get_creases, 1
03229 );
03230 *_bmesh_tags += new TAG_meth<BMESH>(
03231 "polylines", &BMESH::put_polylines, &BMESH::get_polylines, 1
03232 );
03233 *_bmesh_tags += new TAG_meth<BMESH>(
03234 "weak_edges", &BMESH::put_weak_edges, &BMESH::get_weak_edges, 1
03235 );
03236 *_bmesh_tags += new TAG_meth<BMESH>(
03237 "secondary_faces", &BMESH::put_sec_faces, &BMESH::get_sec_faces, 1
03238 );
03239 *_bmesh_tags += new TAG_meth<BMESH>(
03240 "colors", &BMESH::put_colors, &BMESH::get_colors, 1
03241 );
03242 *_bmesh_tags += new TAG_meth<BMESH>(
03243 "texcoords2", &BMESH::put_texcoords2, &BMESH::get_texcoords2, 1
03244 );
03245 *_bmesh_tags += new TAG_meth<BMESH>(
03246 "patch", &BMESH::put_patches, &BMESH::get_patches, 1
03247 );
03248
03249 *_bmesh_tags += new TAG_meth<BMESH>(
03250 "render_style", &BMESH::put_render_style, &BMESH::get_render_style, 1
03251 );
03252 }
03253 return *_bmesh_tags;
03254 }
03255
03256 void
03257 BMESH::put_vertices(TAGformat &d) const
03258 {
03259 Wpt_list verts(nverts());
03260
03261 if (Config::get_var_bool("JOT_SAVE_XFORMED_MESH",false))
03262 for (int i = 0; i< nverts(); i++)
03263 verts += bv(i)->wloc();
03264 else
03265 for (int i = 0; i< nverts(); i++)
03266 verts += bv(i)->loc();
03267
03268
03269
03270
03271 d.id();
03272 if ((*d).ascii()) {
03273 (*d) << "{";
03274 } else {
03275 (*d) << verts.num();
03276 }
03277 for (int i=0; i<verts.num();i++) {
03278 (*d) << " " << verts[i];
03279 (*d).write_newline();
03280 }
03281 if ((*d).ascii()) {
03282 (*d) << "}";
03283 (*d).write_newline();
03284 }
03285 d.end_id();
03286 }
03287
03288 void
03289 BMESH::put_faces(TAGformat &d) const
03290 {
03291 ARRAY<ARRAY<int> > faces(nfaces());
03292
03293 for (int i=0; i<nfaces(); i++) {
03294 ARRAY<int> face;
03295 Bface *f = bf(i);
03296 if (use_new_bface_io) {
03297
03298
03299 if (UVdata::has_uv(f))
03300 continue;
03301 if (!f->is_quad()) {
03302
03303 face += f->v1()->index();
03304 face += f->v2()->index();
03305 face += f->v3()->index();
03306 faces += face;
03307 } else if (f->quad_rep() == f) {
03308
03309 Bvert *a=0, *b=0, *c=0, *d=0;
03310 f->get_quad_verts(a,b,c,d);
03311 assert(a && b && c && d);
03312 face += a->index();
03313 face += b->index();
03314 face += c->index();
03315 face += d->index();
03316 faces += face;
03317 }
03318 } else {
03319
03320 face += f->v1()->index();
03321 face += f->v2()->index();
03322 face += f->v3()->index();
03323 faces += face;
03324 }
03325 }
03326
03327
03328
03329
03330 d.id();
03331 if ((*d).ascii()) {
03332 (*d) << "{";
03333 } else {
03334 (*d) << faces.num();
03335 }
03336 for (int i=0; i<faces.num();i++) {
03337 (*d) << " " << faces[i];
03338 (*d).write_newline();
03339 }
03340 if ((*d).ascii()) {
03341 (*d) << "}";
03342 (*d).write_newline();
03343 }
03344 d.end_id();
03345 }
03346
03347 class UVforIO2
03348 {
03349 public:
03350 ARRAY<int> _face;
03351 ARRAY<UVpt> _uvs;
03352
03353 UVforIO2() {}
03354 UVforIO2(CBface* f)
03355 {
03356 if (!(f && UVdata::has_uv(f)))
03357 return;
03358 if (f->is_quad()) {
03359
03360
03361 if (!f->is_quad_rep())
03362 return;
03363 Bvert *a=0, *b=0, *c=0, *d=0;
03364 UVpt ua, ub, uc, ud;
03365 if (f->get_quad_verts(a,b,c,d) && UVdata::get_quad_uvs(a,b,c,d,ua,ub,uc,ud)) {
03366 assert(a && b && c && d);
03367 _face += a->index();
03368 _face += b->index();
03369 _face += c->index();
03370 _face += d->index();
03371 _uvs += ua;
03372 _uvs += ub;
03373 _uvs += uc;
03374 _uvs += ud;
03375 } else {
03376
03377 err_msg("UVforIO2::UVforIO2: error getting quad uv's; skipping...");
03378 }
03379 } else {
03380 UVpt ua, ub, uc;
03381 if (UVdata::get_uvs(f, ua, ub, uc)) {
03382 _face += f->v1()->index();
03383 _face += f->v2()->index();
03384 _face += f->v3()->index();
03385 _uvs += ua;
03386 _uvs += ub;
03387 _uvs += uc;
03388 } else {
03389
03390 err_msg("UVforIO2::UVforIO2: error getting triangle uv's; skipping...");
03391 }
03392 }
03393 }
03394
03395 int num() const { return _face.num(); }
03396 bool is_good() const { return (num() == 3 || num() == 4) && (num() == _uvs.num()); }
03397
03398
03399 bool operator==(const UVforIO2 &u) const
03400 {
03401
03402 return (_face == u._face && _uvs == u._uvs);
03403 }
03404 };
03405
03406 inline STDdstream&
03407 operator<<(STDdstream &ds, const UVforIO2& v)
03408 {
03409 if (v.is_good()) {
03410 if (ds.ascii())
03411 ds << "{" << v._face << v._uvs << "}";
03412 else
03413 ds << v._face << v._uvs;
03414 }
03415 return ds;
03416 }
03417
03418 inline STDdstream&
03419 operator>>(STDdstream &ds, UVforIO2 &v)
03420 {
03421 if (ds.ascii()) {
03422 char brace;
03423 ds >> brace >> v._face >> v._uvs >> brace;
03424 } else {
03425 ds >> v._face >> v._uvs;
03426 }
03427 return ds;
03428 }
03429
03430
03431 void
03432 BMESH::put_uvfaces(TAGformat &d) const
03433 {
03434
03435
03436
03437
03438
03439 if (!use_new_bface_io)
03440 return;
03441
03442 ARRAY<UVforIO2> uvs(nfaces());
03443
03444 for (int i=0; i<nfaces(); i++) {
03445 UVforIO2 uv(bf(i));
03446 if (uv.is_good())
03447 uvs += uv;
03448 }
03449
03450 if (!uvs.empty()) {
03451 d.id();
03452 *d << uvs;
03453 d.end_id();
03454 }
03455 }
03456
03457 void
03458 BMESH::get_uvfaces(TAGformat &d)
03459 {
03460 ARRAY<UVforIO2> uvs;
03461 *d >> uvs;
03462
03463 if (uvs.empty())
03464 return;
03465
03466 Patch* p = 0;
03467 for (int i=0; i<uvs.num(); i++) {
03468 const UVforIO2& uv = uvs[i];
03469 if (!uv.is_good()) {
03470 err_msg("BMESH::get_uvfaces: skipping bad face:");
03471
03472 iostream i(cerr.rdbuf());
03473 STDdstream e(&i);
03474
03475 e << uv << "\n";
03476 }
03477 switch(uv.num()) {
03478 case 3:
03479
03480 add_face(uv._face[0], uv._face[1], uv._face[2],
03481 uv._uvs[0], uv._uvs[1], uv._uvs[2], p);
03482 break;
03483 case 4:
03484
03485 add_quad(uv._face[0], uv._face[1], uv._face[2], uv._face[3],
03486 uv._uvs[0], uv._uvs[1], uv._uvs[2], uv._uvs[3], p);
03487 break;
03488 default:
03489 assert(0);
03490 }
03491 }
03492
03493 changed(TOPOLOGY_CHANGED);
03494 }
03495
03496 void
03497 BMESH::put_creases(TAGformat &d) const
03498 {
03499 ARRAY<Point2i> creases;
03500
03501 for (int i=0; i<nedges(); i++) {
03502 Bedge *e = be(i);
03503 if (e->is_crease())
03504 creases += Point2i(e->v(1)->index(), e->v(2)->index());
03505 }
03506
03507
03508 if (creases.num() == 0)
03509 return;
03510
03511 d.id();
03512 *d << creases;
03513 d.end_id();
03514
03515 }
03516
03517
03518 void
03519 BMESH::put_polylines(TAGformat &d) const
03520 {
03521 ARRAY<Point2i> polylines;
03522
03523 for (int i=0; i<nedges(); i++) {
03524 Bedge *e = be(i);
03525 if (e->is_polyline())
03526 polylines += Point2i(e->v(1)->index(), e->v(2)->index());
03527 }
03528
03529
03530 if (polylines.num() == 0)
03531 return;
03532
03533 d.id();
03534 *d << polylines;
03535 d.end_id();
03536
03537 }
03538
03539 void
03540 BMESH::put_weak_edges(TAGformat &d) const
03541 {
03542 if (use_new_bface_io)
03543 return;
03544
03545 ARRAY<Point2i> weak_edges;
03546
03547 for (int i=0; i<nedges(); i++) {
03548 Bedge *e = be(i);
03549 if (e->is_weak())
03550 weak_edges += Point2i(e->v(1)->index(), e->v(2)->index());
03551 }
03552
03553 if (weak_edges.empty())
03554 return;
03555
03556 d.id();
03557 *d << weak_edges;
03558 d.end_id();
03559 }
03560
03561 void
03562 BMESH::put_sec_faces(TAGformat &d) const
03563 {
03564 ARRAY<Point3i> sec_faces;
03565
03566 for (int i=0; i<nfaces(); i++) {
03567 Bface *f = bf(i);
03568 if (f && f->is_secondary())
03569 sec_faces += Point3i(f->v1()->index(), f->v2()->index(), f->v3()->index());
03570 }
03571
03572 if (sec_faces.empty())
03573 return;
03574
03575 d.id();
03576 *d << sec_faces;
03577 d.end_id();
03578
03579 }
03580
03581
03582 class UVforIO
03583 {
03584 public:
03585 int _face;
03586 UVpt _uv1;
03587 UVpt _uv2;
03588 UVpt _uv3;
03589
03590 UVforIO() {}
03591 UVforIO(int f, CUVpt& uv1, CUVpt& uv2, CUVpt& uv3) : _face(f), _uv1(uv1), _uv2(uv2), _uv3(uv3) {}
03592
03593 UVpt& uv(int i) {if (i==1)
03594 return _uv1; else if (i==2)
03595 return _uv2; else { assert(i==3); return _uv3;} }
03596
03597 bool operator ==(const UVforIO &p) const
03598 { return _face==p._face && _uv1==p._uv1 && _uv2==p._uv2 && _uv3==p._uv3; }
03599
03600 };
03601
03602 inline STDdstream &operator<<(STDdstream &ds, const UVforIO &v)
03603 {
03604 if (ds.ascii())
03605 ds << "{" << v._face << v._uv1 << v._uv2 << v._uv3 << "}";
03606 else
03607 ds << v._face << v._uv1 << v._uv2 << v._uv3;
03608 return ds;
03609 }
03610
03611 inline STDdstream &operator>>(STDdstream &ds, UVforIO &v)
03612 {
03613 if (ds.ascii()) {
03614 char brace;
03615 ds >> brace >> v._face >> v._uv1 >> v._uv2 >> v._uv3 >> brace;
03616 } else
03617 ds >> v._face >> v._uv1 >> v._uv2 >> v._uv3;
03618 return ds;
03619 }
03620
03621 void
03622 BMESH::put_texcoords2(TAGformat &d) const
03623 {
03624
03625 if (use_new_bface_io)
03626 return;
03627
03628 ARRAY<UVforIO> texcoords2;
03629
03630 for (int i=0; i<nfaces(); i++) {
03631 UVdata* uvdata = UVdata::lookup(bf(i));
03632 if (uvdata)
03633 texcoords2 += UVforIO(i, uvdata->uv(1), uvdata->uv(2), uvdata->uv(3));
03634 }
03635
03636
03637 if (texcoords2.num() == 0)
03638 return;
03639
03640 d.id();
03641 *d << texcoords2;
03642 d.end_id();
03643
03644 }
03645
03646
03647 void
03648 BMESH::put_render_style(TAGformat &d) const
03649 {
03650
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662
03663
03664
03665
03666 }
03667
03668 void
03669 BMESH::put_colors(TAGformat &d) const
03670 {
03671
03672
03673 if ((nverts()==0) || (!_verts[0]->has_color()))
03674 return;
03675
03676
03677 ARRAY<COLOR> colors(nverts());
03678
03679 for (int i=0; i<nverts(); i++)
03680 colors += bv(i)->color();
03681
03682 d.id();
03683 *d << colors;
03684 d.end_id();
03685
03686 }
03687
03688 void
03689 BMESH::put_patches(TAGformat &d) const
03690 {
03691
03692
03693
03694 if (_patches.num() == 1 && _patches[0]->gtextures().empty())
03695 return;
03696
03697 for (int i=0;i<_patches.num();i++) {
03698 d.id();
03699 _patches[i]->format(*d);
03700 d.end_id();
03701 }
03702 }
03703
03704
03705 void
03706 BMESH::get_vertices(TAGformat &d)
03707 {
03708
03709
03710
03711
03712
03713 Wpt_list locs;
03714 *d >> locs;
03715
03716
03717
03718 if (nverts()) {
03719 if (locs.num() == nverts()) {
03720 for (int i=0; i < locs.num(); i++)
03721 _verts[i]->set_loc(locs[i]);
03722 changed(VERT_POSITIONS_CHANGED);
03723 } else {
03724 err_msg(
03725 "BMESH::get_vertices() - Error! Num verts in mesh (%d) doesn't match num in update (%d)!\n",
03726 nverts(), locs.num());
03727 }
03728 } else {
03729 _verts.realloc(locs.num());
03730 _edges.realloc(3*locs.num());
03731
03732 for (int i=0; i < locs.num(); i++) {
03733
03734
03735 Bvert* v = new_vert(locs[i]);
03736 add_vertex(v);
03737 }
03738
03739
03740
03741
03742 }
03743 }
03744
03745 void
03746 BMESH::get_faces(TAGformat &d)
03747 {
03748 assert(nfaces() == 0);
03749
03750 ARRAY<ARRAY<int> > faces;
03751 *d >> faces;
03752
03753 _faces.realloc(faces.num());
03754
03755
03756
03757
03758
03759 Patch* p = 0;
03760 for (int i=0; i<faces.num(); i++) {
03761 CARRAY<int>& face = faces[i];
03762 switch(face.num()) {
03763
03764 case 3:
03765
03766 add_face(face[0], face[1], face[2], p);
03767 break;
03768 case 4:
03769
03770 add_quad(face[0], face[1], face[2], face[3], p);
03771 break;
03772
03773 default: {
03774 err_msg("BMESH::get_faces: error: %d-gon found, skipping...", face.num());
03775
03776
03777
03778
03779
03780
03781 iostream i(cerr.rdbuf());
03782 STDdstream e(&i);
03783 e << face << "\n";
03784 }
03785 }
03786 }
03787
03788 changed(TOPOLOGY_CHANGED);
03789 }
03790
03791 void
03792 BMESH::get_creases(TAGformat &d)
03793 {
03794 ARRAY<Point2i> creases;
03795 *d >> creases;
03796
03797 for (int i=0; i<creases.num(); i++)
03798 set_crease(creases[i][0],creases[i][1]);
03799
03800 changed(CREASES_CHANGED);
03801 }
03802
03803 void
03804 BMESH::get_polylines(TAGformat &d)
03805 {
03806 ARRAY<Point2i> polylines;
03807 *d >> polylines;
03808
03809 for (int i=0; i<polylines.num(); i++)
03810 add_edge(polylines[i][0],polylines[i][1]);
03811
03812 if (Config::get_var_bool("BMESH_BUILD_POLYSTRIPS",false) &&
03813 polylines.num() > 0)
03814 build_polyline_strips();
03815 }
03816
03817 void
03818 BMESH::get_weak_edges(TAGformat &d)
03819 {
03820 ARRAY<Point2i> weak_edges;
03821 *d >> weak_edges;
03822
03823 bool debug = Config::get_var_bool("DEBUG_WEAK_EDGES",false);
03824 err_adv(debug, "BMESH::get_weak_edges: reading %d weak edges",
03825 weak_edges.num());
03826
03827 int count=0;
03828 for (int i=0; i<weak_edges.num(); i++)
03829 if (set_weak_edge(weak_edges[i][0],weak_edges[i][1]))
03830 count++;
03831 err_adv(debug, "set %d/%d weak edges", count, weak_edges.num());
03832 }
03833
03834 void
03835 BMESH::get_sec_faces(TAGformat &d)
03836 {
03837 int i;
03838 ARRAY<Point3i> sec_faces;
03839
03840 *d >> sec_faces;
03841
03842 Bface_list sec_faces_list;
03843
03844 for (i=0; i<sec_faces.num(); i++) {
03845 Bface* face = lookup_face(sec_faces[i]);
03846
03847 if (!face)
03848 cerr << "BMESH::get_sec_faces - error: could not find secondary face"
03849 << endl;
03850 else
03851 sec_faces_list += face;
03852 }
03853
03854 if (sec_faces_list.empty())
03855 return;
03856
03857 sec_faces_list.push_layer();
03858
03859 for (i=0; i<nedges(); i++)
03860 be(i)->fix_multi();
03861 }
03862
03863
03864 void
03865 BMESH::get_texcoords2(TAGformat &d)
03866 {
03867 static double UV_RESOLUTION = Config::get_var_dbl("UV_RESOLUTION",0,true);
03868
03869 ARRAY<UVforIO> texcoords2;
03870 *d >> texcoords2;
03871
03872 for (int i=0; i<texcoords2.num(); i++) {
03873 if (_faces.valid_index(texcoords2[i]._face)) {
03874
03875
03876 if (UV_RESOLUTION>0) {
03877 for (int j=1; j<4; j++) {
03878 UVpt &uv = texcoords2[i].uv(j);
03879 double r;
03880 uv[0] -= r = fmod(uv[0],UV_RESOLUTION);
03881 if (2.0*fabs(r) > UV_RESOLUTION)
03882 uv[0] += ((r>0)?(UV_RESOLUTION):(-UV_RESOLUTION));
03883 uv[1] -= r = fmod(uv[1],UV_RESOLUTION);
03884 if (2.0*fabs(r) > UV_RESOLUTION)
03885 uv[1] += ((r>0)?(UV_RESOLUTION):(-UV_RESOLUTION));
03886 }
03887 }
03888
03889 UVdata::set
03890 (bf(texcoords2[i]._face),
03891 texcoords2[i]._uv1,
03892 texcoords2[i]._uv2,
03893 texcoords2[i]._uv3);
03894 } else {
03895 err_msg("BMESH::read_texcoords2() - ERROR! Invalid face index %d",
03896 texcoords2[i]._face);
03897 }
03898
03899
03900 }
03901
03902
03903
03904 }
03905
03906 void
03907 BMESH::get_render_style(TAGformat &d)
03908 {
03909
03910
03911
03912
03913 str_ptr style = (*d).get_string_with_spaces();
03914
03915
03916
03917
03918
03919 }
03920
03921 void
03922 BMESH::get_colors(TAGformat &d)
03923 {
03924
03925 ARRAY<COLOR> colors;
03926 *d >> colors;
03927
03928 if (colors.num() != nverts()) {
03929 err_msg("BMESH::get_colors: warning: %d colors for %d verts",
03930 colors.num(), nverts());
03931 err_msg(" rejecting vert colors");
03932 } else {
03933 for (int i=0; i < colors.num(); i++)
03934 _verts[i]->set_color(colors[i]);
03935 changed(VERT_COLORS_CHANGED);
03936 }
03937 }
03938
03939 void
03940 BMESH::get_patches(TAGformat &d)
03941 {
03942 str_ptr patchname;
03943 *d >> patchname;
03944
03945
03946
03947 Patch *patch = new_patch();
03948
03949 patch->decode(*d);
03950
03951 changed(PATCHES_CHANGED);
03952 }
03953
03954
03955
03956
03957 STDdstream &
03958 BMESH::format(STDdstream &ds) const
03959 {
03960 STDdstream &ret = BODY::format(ds);
03961
03962 return ret;
03963 }
03964
03965 STDdstream &
03966 BMESH::decode(STDdstream &ds)
03967 {
03968
03969 STDdstream &ret = BODY::decode(ds);
03970
03971 make_patch_if_needed();
03972
03973
03974
03975
03976
03977 if (is_points() && Config::get_var_bool("BMESH_BUILD_VERT_STRIPS",false))
03978 build_vert_strips();
03979
03980 return ret;
03981 }
03982
03983 void
03984 BMESH::recenter()
03985 {
03986 if (nverts() < 1) {
03987 err_msg("BMESH::recenter: mesh is empty");
03988 return;
03989 }
03990
03991 static Wpt_list pts(8);
03992 if (!(get_bb().points(pts))) {
03993 err_msg("BMESH::recenter: can't get bounding box");
03994 return;
03995 }
03996 Wpt c = get_bb().center();
03997
03998 double s = 0;
03999 for (int i=0; i<8; i++)
04000 s = max(s, pts[i].dist(c));
04001
04002 if (s<1e-12) {
04003 err_msg("BMESH::recenter: mesh is too tiny");
04004 return;
04005 }
04006
04007 double len = Config::get_var_dbl("JOT_REDENTER_LEN", 15);
04008 MOD::tick();
04009 transform(Wtransf::scaling(Wpt::Origin(), len/s) *
04010 Wtransf::translation(Wpt::Origin() - get_bb().center()), MOD());
04011
04012 changed(VERT_POSITIONS_CHANGED);
04013 }
04014
04015 double
04016 BMESH::avg_len() const
04017 {
04018 if (!_avg_edge_len_valid) {
04019 double ret = 0;
04020 for (int k=_edges.num()-1; k>=0; k--)
04021 ret += _edges[k]->length();
04022 if (!_edges.empty())
04023 ret /= _edges.num();
04024 ((BMESH*) this)->_avg_edge_len_valid = 1;
04025 ((BMESH*) this)->_avg_edge_len = ret;
04026 }
04027 return _avg_edge_len;
04028 }
04029
04030 BMESHptr
04031 BMESH::merge(BMESHptr m1, BMESHptr m2)
04032 {
04033
04034
04035
04036
04037
04038
04039
04040
04041
04042
04043
04044
04045 if (!m1 && !m2) {
04046 err_msg("BMESH::merge: warning: both meshes are null.");
04047 return BMESHptr(0);
04048 } else if (!m1) {
04049 return m2;
04050 } else if (!m2) {
04051 return m1;
04052 } else if (m1->class_name() != m2->class_name()) {
04053 cerr << "BMESH::merge: bad luck! the meshes are different types:\n "
04054 << m1->class_name()
04055 << " and "
04056 << m2->class_name()
04057 << endl;
04058 return BMESHptr(0);
04059 }
04060
04061
04062 if (m1 == m2)
04063 return m1;
04064
04065
04066
04067
04068
04069
04070
04071
04072 if (m2->empty()) {
04073 err_msg("BMESH::merge: smaller mesh is empty");
04074 return m1;
04075 }
04076
04077
04078 m2->transform(m1->inv_xform()*m2->xform(), MOD());
04079
04080
04081
04082 m1->_merge(m2);
04083
04084 return m1;
04085 }
04086
04087 void
04088 BMESH::_merge(BMESH* m)
04089 {
04090
04091
04092
04093
04094
04095
04096 assert(m);
04097
04098
04099 _verts.append(m->_verts);
04100 _edges.append(m->_edges);
04101 _faces.append(m->_faces);
04102
04103 m->_verts.clear();
04104 m->_edges.clear();
04105 m->_faces.clear();
04106
04107
04108 while (!m->_patches.empty()) {
04109 _patches += m->_patches.pop();
04110 _patches.last()->set_mesh(this);
04111 }
04112
04113
04114 _drawables.operator+=(m->_drawables);
04115 m->_drawables.clear();
04116
04117
04118 if (_type_valid && m->_type_valid) {
04119 _type |= m->_type;
04120
04121
04122 if (_type & OPEN_SURFACE)
04123 _type &= ~CLOSED_SURFACE;
04124
04125
04126 _vert_locs.clear();
04127 BODY::_edges.reset();
04128 _body = 0;
04129 _bb.reset();
04130
04131
04132 _version++;
04133
04134 } else {
04135
04136 changed(TOPOLOGY_CHANGED);
04137 }
04138
04139
04140 m->changed(TOPOLOGY_CHANGED);
04141
04142
04143 BMESHobs::broadcast_merge(this, &*m);
04144 }
04145
04146
04147 void
04148 BMESH::grow_mesh_equivalence_class(
04149 Bvert* v,
04150 ARRAY<Bface*> &faces,
04151 ARRAY<Bedge*> &edges,
04152 ARRAY<Bvert*> &verts)
04153
04154 {
04155 if (v->flag() == 0)
04156 return;
04157
04158 for (int i=0; i<v->degree(); i++) {
04159 Bedge* nbr_e = v->e(i);
04160 Bvert* nbr_v = v->nbr(i);
04161
04162 for (int j=1; j<=2; j++) {
04163 Bface *f = nbr_e->f(j);
04164 if (f && !f->flag()) {
04165 f->set_flag();
04166 faces += f;
04167 }
04168 }
04169
04170 if (!nbr_e->flag()) {
04171 nbr_e->set_flag();
04172 edges += nbr_e;
04173 }
04174
04175 if (!nbr_v->flag()) {
04176 nbr_v->set_flag();
04177 verts += nbr_v;
04178
04179 grow_mesh_equivalence_class(nbr_v, faces, edges, verts);
04180 }
04181 }
04182 }
04183
04184 ARRAY<BMESH*>
04185 BMESH::split_components()
04186 {
04187
04188
04189
04190 ARRAY<BMESH*> new_meshes;
04191
04192
04193 _verts.clear_flags();
04194 _edges.clear_flags();
04195 _faces.clear_flags();
04196
04197
04198
04199
04200
04201 Bvert_list tmp_verts = _verts;
04202
04203 for (int i=0; i<tmp_verts.num(); i++) {
04204 Bvert* v = tmp_verts[i];
04205 if (!v->flag()) {
04206
04207
04208 ARRAY<Bface*> faces;
04209 ARRAY<Bedge*> edges;
04210 ARRAY<Bvert*> verts;
04211
04212
04213
04214 v->set_flag();
04215 verts += v;
04216
04217
04218 grow_mesh_equivalence_class(v, faces, edges, verts);
04219
04220
04221 if (i == 0)
04222 continue;
04223
04224
04225 BMESH* m = (BMESH*)dup();
04226 new_meshes += m;
04227
04228 int t;
04229 for (t=0; t<verts.num(); t++) {
04230 _verts -= verts[t];
04231 m->add_vertex(verts[t]);
04232 }
04233
04234 for (t=0; t<edges.num(); t++) {
04235 _edges -= edges[t];
04236 m->add_edge(edges[t]);
04237 }
04238
04239
04240
04241 Patch* p = m->new_patch();
04242 for (t=0; t<faces.num(); t++) {
04243 _faces -= faces[t];
04244 m->add_face(faces[t],p);
04245 }
04246
04247 if (m != this)
04248 m->changed(TOPOLOGY_CHANGED);
04249 }
04250 }
04251
04252
04253 clean_patches();
04254
04255 changed(TOPOLOGY_CHANGED);
04256
04257 BMESHobs::broadcast_split(this, new_meshes);
04258
04259 return new_meshes;
04260 }
04261
04262 ARRAY<Bface_list>
04263 BMESH::get_components() const
04264 {
04265
04266
04267
04268 ARRAY<Bface_list> ret;
04269
04270
04271
04272 _faces.set_flags(1);
04273
04274 for (int i=0; i<_faces.num(); i++) {
04275 Bface* f = bf(i);
04276 if (f->flag() == 1) {
04277 Bface_list component;
04278 component.grow_connected(f);
04279 assert(!component.empty());
04280 ret += component;
04281 }
04282 }
04283 return ret;
04284 }
04285
04286 void
04287 BMESH::split_tris(Bface* start_face, Wplane plane, ARRAY<Bvert*>& new_vs)
04288 {
04289 Bedge* curr_edge = 0;
04290 for (int ed=1; ed<4; ed++)
04291 if (start_face->e(ed)->which_side(plane) == 0) {
04292 curr_edge = start_face->e(ed);
04293 break;
04294 }
04295
04296 if (!curr_edge) {
04297 cerr << "BMESH::split_tris: lost my edge, can't go on" << endl;
04298 return;
04299 }
04300
04301 Bvert *new_pt;
04302 Bvert *last_pt = 0;
04303 Bvert *start_pt = 0;
04304
04305 do {
04306 if (last_pt) {
04307 Bface_list faces;
04308 last_pt->get_faces(faces);
04309 for (int i=0; i<faces.num(); i++) {
04310 curr_edge = faces[i]->opposite_edge(last_pt);
04311 if (curr_edge->which_side(plane) == 0) {
04312 if (new_vs.empty())
04313 break;
04314 else {
04315 Bvert* oldv = new_vs[new_vs.num()-2];
04316 if (!faces[i]->contains(oldv))
04317 break;
04318 }
04319 }
04320 }
04321 }
04322
04323 Wpt p1 = curr_edge->v1()->loc();
04324 Wpt p2 = curr_edge->v2()->loc();
04325 double d1 = fabs(plane.dist(p2));
04326 double d2 = fabs(plane.dist(p1));
04327 Wpt pt = ((d1 * p1) + (d2 * p2)) / (d1+d2);
04328
04329 new_pt = split_edge(curr_edge, pt);
04330 new_vs += new_pt;
04331
04332 if (!last_pt)
04333 start_pt = new_pt;
04334
04335 last_pt = new_pt;
04336 } while (new_vs.num() < 3 || last_pt->lookup_edge(start_pt) == 0);
04337 }
04338
04339
04340 void
04341 BMESH::kill_component(Bvert *start_vert)
04342 {
04343 ARRAY<Bface*> faces;
04344 ARRAY<Bedge*> edges;
04345 ARRAY<Bvert*> verts;
04346
04347 int i;
04348 for (i=0; i<nfaces(); i++)
04349 _faces[i]->clear_flag();
04350 for (i=0; i<nedges(); i++)
04351 _edges[i]->clear_flag();
04352 for (i=0; i<nverts(); i++)
04353 _verts[i]->clear_flag();
04354
04355 start_vert->set_flag();
04356 verts += start_vert;
04357
04358 grow_mesh_equivalence_class(start_vert, faces, edges, verts);
04359
04360 cerr << "removed " << faces.num() << " faces, "
04361 << edges.num() << " edges, " << verts.num() << " vertices" << endl;
04362
04363 int t;
04364 for (t=0; t<faces.num(); t++)
04365 delete_face(faces[t]);
04366
04367 for (t=0; t<edges.num(); t++)
04368 delete_edge(edges[t]);
04369
04370 for (t=0; t<verts.num(); t++)
04371 delete_vert(verts[t]);
04372
04373 changed(TOPOLOGY_CHANGED);
04374 }
04375
04376
04377
04378
04379 int
04380 BMESH::tex_already_exists(Cstr_ptr &name) const
04381 {
04382 int exists = 0;
04383 if (patches().num()) {
04384 for (int i = 0; !exists && i < patches().num(); i++) {
04385 exists = patches()[i]->cur_tex()->type() == name;
04386 }
04387 }
04388 return exists;
04389 }
04390
04391 double
04392 BMESH::z_span() const
04393 {
04394 double a, b;
04395 return z_span(a, b);
04396 }
04397
04398 double
04399 BMESH::z_span(double& zmin, double& zmax) const
04400 {
04401
04402
04403
04404
04405
04406
04407 static Wpt_list pts(8);
04408
04409 if (!(((BMESH*)this)->get_bb().points(pts)))
04410 return 2.0;
04411
04412 pts.xform(obj_to_ndc());
04413
04414 zmin = pts[0][2];
04415 zmax = zmin;
04416 for (int i=1; i<pts.num(); i++) {
04417 double z = pts[i][2];
04418 zmin = min(zmin, z);
04419 zmax = max(zmax, z);
04420 }
04421
04422 return (zmax - zmin);
04423 }
04424
04425
04426 void
04427 BMESH::compute_pix_size()
04428 {
04429
04430
04431
04432
04433
04434 _pix_size_stamp = VIEW::stamp();
04435 BBOX bb = xform()*get_bb();
04436 double size = bb.dim().length();
04437 Wpt pos = bb.center();
04438 Wvec perp = VIEW::peek_cam()->data()->right_v();
04439 assert(!perp.is_null());
04440 _pix_size = VEXEL(pos, size * perp).length();
04441 }
04442
04443
04444
04445
04446
04447
04448
04449 void
04450 BMESH::set_render_style(Cstr_ptr& s)
04451 {
04452 if (_render_style.empty())
04453 push_render_style(s) ;
04454 else
04455 _render_style.last() = s;
04456 changed(RENDERING_CHANGED);
04457 }
04458
04459 void
04460 BMESH::push_render_style(Cstr_ptr& s)
04461 {
04462 _render_style += s;
04463 changed(RENDERING_CHANGED);
04464 }
04465
04466 void
04467 BMESH::pop_render_style()
04468 {
04469 if (!_render_style.empty())
04470 _render_style.pop();
04471 changed(RENDERING_CHANGED);
04472 }
04473
04474 Cstr_ptr&
04475 BMESH::render_style() const
04476 {
04477 return _render_style.empty() ? str_ptr::null_str() : _render_style.last();
04478 }
04479
04480
04481
04482
04483 void
04484 BMESHray::check(
04485 double d,
04486 int is_surface,
04487 double d_2d,
04488 CGELptr &g,
04489 CWvec &n,
04490 CWpt &nearpt,
04491 CWpt &surfl,
04492 APPEAR *app,
04493 CXYpt &tex_coord
04494 )
04495 {
04496 if (test(d, is_surface, d_2d)) {
04497
04498 set_simplex(0);
04499 RAYhit::check(d, is_surface, d_2d, g, n, nearpt, surfl, app, tex_coord);
04500 }
04501 }
04502
04503
04504
04505
04506 void
04507 BMESHobs::broadcast_change(BMESH* m, BMESH::change_t change)
04508 {
04509
04510 _all_observers.notify_change(m, change);
04511
04512
04513 bmesh_obs_list(m).notify_change(m, change);
04514 }
04515
04516 void
04517 BMESHobs::broadcast_xform(BMESH* mesh, CWtransf& xf, CMOD& mod)
04518 {
04519
04520 _all_observers.notify_xform(mesh, xf, mod);
04521
04522
04523 bmesh_obs_list(mesh).notify_xform(mesh, xf, mod);
04524 }
04525
04526 void
04527 BMESHobs::broadcast_merge(BMESH* joined, BMESH* removed)
04528 {
04529
04530
04531
04532
04533 _all_observers.notify_merge(joined, removed);
04534
04535
04536
04537
04538
04539
04540
04541
04542
04543
04544 BMESHobs_list joined_obs = bmesh_obs_list(joined);
04545 joined_obs.notify_merge(joined, removed);
04546
04547
04548
04549
04550 BMESHobs_list removed_obs = bmesh_obs_list(removed);
04551 removed_obs.notify_merge(joined, removed);
04552 }
04553
04554 void
04555 BMESHobs::broadcast_split(BMESH* m, CARRAY<BMESH*>& new_meshes)
04556 {
04557
04558 _all_observers.notify_split(m, new_meshes);
04559
04560
04561
04562
04563 BMESHobs_list list = bmesh_obs_list(m);
04564 list.notify_split(m, new_meshes);
04565 }
04566
04567 void
04568 BMESHobs::broadcast_subdiv_gen(BMESH* m)
04569 {
04570
04571 _all_observers.notify_subdiv_gen(m);
04572
04573
04574 bmesh_obs_list(m).notify_subdiv_gen(m);
04575 }
04576
04577 void
04578 BMESHobs::broadcast_delete(BMESH* m)
04579 {
04580
04581 _all_observers.notify_delete(m);
04582
04583
04584
04585
04586 BMESHobs_list list = bmesh_obs_list(m);
04587 list.notify_delete(m);
04588 }
04589
04590 void
04591 BMESHobs::broadcast_sub_delete(BMESH* m)
04592 {
04593
04594 _all_observers.notify_sub_delete(m);
04595
04596
04597 bmesh_obs_list(m).notify_sub_delete(m);
04598 }
04599
04600 void
04601 BMESHobs::broadcast_update_request(BMESH* m)
04602 {
04603
04604
04605
04606 bmesh_obs_list(m).notify_update_request(m);
04607
04608
04609 }
04610
04611
04612
04613
04614 void
04615 BMESHobs_list::notify_change(BMESH* mesh, BMESH::change_t change) const
04616 {
04617 for (int i=0; i<_num; i++)
04618 _array[i]->notify_change(mesh, change);
04619 }
04620
04621 void
04622 BMESHobs_list::notify_xform(BMESH* mesh, CWtransf& xf, CMOD& m) const
04623 {
04624 for (int i=0; i<_num; i++)
04625 _array[i]->notify_xform(mesh, xf, m);
04626 }
04627
04628 void
04629 BMESHobs_list::notify_merge(BMESH* m1, BMESH* m2) const
04630 {
04631 for (int i=0; i<_num; i++)
04632 _array[i]->notify_merge(m1, m2);
04633 }
04634
04635 void
04636 BMESHobs_list::notify_split(BMESH* mesh, CARRAY<BMESH*>& pieces) const
04637 {
04638 for (int i=0; i<_num; i++)
04639 _array[i]->notify_split(mesh, pieces);
04640 }
04641
04642 void
04643 BMESHobs_list::notify_subdiv_gen(BMESH* mesh) const
04644 {
04645 for (int i=0; i<_num; i++)
04646 _array[i]->notify_subdiv_gen(mesh);
04647 }
04648
04649 void
04650 BMESHobs_list::notify_delete(BMESH* mesh) const
04651 {
04652 for (int i=0; i<_num; i++)
04653 _array[i]->notify_delete(mesh);
04654 }
04655
04656 void
04657 BMESHobs_list::notify_sub_delete(BMESH* mesh) const
04658 {
04659 for (int i=0; i<_num; i++)
04660 _array[i]->notify_sub_delete(mesh);
04661 }
04662
04663 void
04664 BMESHobs_list::notify_update_request(BMESH* mesh) const
04665 {
04666 for (int i=0; i<_num; i++)
04667 _array[i]->notify_update_request(mesh);
04668 }
04669
04670 void
04671 BMESHobs_list::print_names() const
04672 {
04673 for (int i=0; i<_num; i++)
04674 cerr << _array[i]->name() << " ";
04675 cerr << endl;
04676 }
04677
04678