00001
00007 #ifdef HAVE_CONFIG_H
00008 #include <tumble-conf.h>
00009 #endif
00010
00011 #include "visualization.h"
00012
00013 #include <iostream>
00014 #include <cstdio>
00015 #include <cstdlib>
00016
00017 #include <GL/gl.h>
00018 #include <GL/glu.h>
00019 #include <GL/freeglut_std.h>
00020
00021 #include "beziermesh.h"
00022 #include "boundarymesh.h"
00023 #include "hash_map.h"
00024 #include "simulation.h"
00025 #include "spline.h"
00026 #include "timehelp.h"
00027
00028 using namespace std;
00029 using namespace hashers;
00030
00038 Visualization::Visualization(Simulation *sim, int _screen_width, int _screen_height)
00039 {
00040 if ( !sim ){
00041 cout<<"Visualization --- received bad simulation!"<<endl;
00042 exit(-1);
00043 }
00044 initialize(sim->get_bezier_mesh(), sim->get_boundary_mesh(), _screen_width, _screen_height);
00045 }
00046
00053 Visualization::Visualization(Simulation *sim)
00054 {
00055 if ( !sim ){
00056 cout<<"Visualization --- received bad simulation!"<<endl;
00057 exit(-1);
00058 }
00059 initialize(sim->get_bezier_mesh(), sim->get_boundary_mesh());
00060 }
00061
00070 Visualization::Visualization(BezierMesh *_bezier_mesh, BoundaryMesh *_bdry_mesh, int _screen_width, int _screen_height)
00071 {
00072 initialize(_bezier_mesh, _bdry_mesh, _screen_width, _screen_height);
00073 }
00074
00081 Visualization::Visualization(BezierMesh *_bezier_mesh, BoundaryMesh *_bdry_mesh)
00082 {
00083 initialize(_bezier_mesh, _bdry_mesh);
00084 }
00085
00092 Visualization::Visualization(BezierMesh *_bezier_mesh, BoundaryMesh *_bdry_mesh, bool _project)
00093 {
00094 initialize(_bezier_mesh, _bdry_mesh, -1, -1, true);
00095 }
00096
00107 void Visualization::initialize(BezierMesh *_bezier_mesh, BoundaryMesh *_bdry_mesh, int _screen_width, int _screen_height, bool _project)
00108 {
00109 if ( !_bezier_mesh || !_bdry_mesh ){
00110 cout<<"Visualization::initialize --- received bad mesh!"<<endl;
00111 exit(-1);
00112 }
00113 bezier_mesh = _bezier_mesh;
00114 bdry_mesh = _bdry_mesh;
00115
00116 if(_screen_width <= 0 ) _screen_width = 400;
00117 if(_screen_height <= 0 ) _screen_height = 400;
00118
00119 if (!_project)
00120 {
00121 compute_world_size();
00122 view_top = world_top;
00123 view_bot = world_bot;
00124 }
00125
00126
00127 default_opengl_color_map( colormap );
00128 edge_draw_acc = 8;
00129 face_draw_acc = 12;
00130
00131 init_zoom();
00132 resize(_screen_width, _screen_height);
00133 }
00134
00135
00137 Visualization::~Visualization()
00138 {
00139 return;
00140 }
00141
00149 Pic* Visualization::dump_pixels(Pic* &p)
00150 {
00151 p = pic_alloc(screen_width,screen_height,3,NULL);
00152 if(!p) return p;
00153 for(int i= screen_height - 1; i >= 0; i--){
00154 glReadPixels(0,screen_height - i, screen_width, 1,
00155 GL_RGB, GL_UNSIGNED_BYTE,
00156 &p->pix[i * p->nx * p->bpp]);
00157 }
00158 return p;
00159 }
00160
00161 int Visualization::map_color(int idx, const Color &color)
00162 {
00163 if( !color.is_valid() ) return -1;
00164 colormap[idx] = color;
00165 return 0;
00166 }
00167
00168
00191 int Visualization::get_norms(vector<double> &min, vector<double> &max)
00192 {
00193 int len = bezier_mesh->data_length();
00194
00195 min.clear();
00196 max.clear();
00197
00198 BezierMesh::Vertex_Hash_T::iterator vi;
00199 for(vi = bezier_mesh->get_vertices_begin();
00200 vi != bezier_mesh->get_vertices_end(); ++vi) {
00201 const LinearData& d = (*vi)->get_dp();
00202 for(int i = 0; i<len; i++){
00203 double data = d[i];
00204 if((signed)min.size() < i+1) min.push_back(data);
00205 else if(data < min[i]) min[i] = data;
00206
00207 if((signed)max.size() < i+1) max.push_back(data);
00208 else if(data > max[i]) max[i] = data;
00209 }
00210 }
00211 return len;
00212 }
00213
00219 int Visualization::write_jpeg(char *filename)
00220 {
00221 int val;
00222 if(!filename) return FALSE;
00223 char file[MAX_FILENAME];
00224 if( add_filename_extension(filename, "jpg", file, MAX_FILENAME) ) return -1;
00225
00226 Pic *p=NULL;
00227 val = jpeg_write(file, dump_pixels(p));
00228 pic_free(p);
00229 return val;
00230 }
00231
00237 int Visualization::write_tiff(char *filename)
00238 {
00239 int val;
00240 if(!filename) return FALSE;
00241 char file[MAX_FILENAME];
00242 if( add_filename_extension(filename, "tiff", file, MAX_FILENAME) ) return -1;
00243 Pic *p=NULL;
00244 val = tiff_write(file, dump_pixels(p));
00245 pic_free(p);
00246 return val;
00247 }
00248
00254 int Visualization::write_ppm(char *filename)
00255 {
00256 int val;
00257 if(!filename) return FALSE;
00258 char file[MAX_FILENAME];
00259
00260 if( add_filename_extension(filename, "ppm", file, MAX_FILENAME) ) return -1;
00261
00262 Pic *p=NULL;
00263 val = ppm_write(file, dump_pixels(p));
00264 pic_free(p);
00265
00266 return val;
00267 }
00268
00269 void Visualization::draw( const Color &bdry_color, const Color &edge_color){
00270 BezierMesh::Bezier_Edge_Hash_T::const_iterator ze;
00271 for(ze = bezier_mesh->get_edges_begin(); ze != bezier_mesh->get_edges_end(); ++ze) {
00272 draw_bezier_edge(*ze, edge_color);
00273 }
00274
00275 BoundaryMesh::Boundary_Edge_Hash_T::const_iterator be;
00276 for(be = bdry_mesh->get_edges_begin(); be != bdry_mesh->get_edges_end(); ++be) {
00277 draw_boundary_edge(*be, bdry_color);
00278 }
00279 }
00280
00281 void Visualization::draw_bezier( const Color &edge_color, const Color &tri_color)
00282 {
00283 BezierMesh::Bezier_Face_Hash_T::const_iterator zt;
00284 for(zt = bezier_mesh->get_faces_begin(); zt != bezier_mesh->get_faces_end(); ++zt) {
00285 draw_bezier_triangle(*zt, tri_color);
00286 }
00287
00288 BezierMesh::Bezier_Edge_Hash_T::const_iterator ze;
00289 for(ze = bezier_mesh->get_edges_begin(); ze != bezier_mesh->get_edges_end(); ++ze) {
00290 draw_bezier_edge(*ze, edge_color);
00291 }
00292
00293 }
00294
00295 void Visualization::draw_solid( const Color &bdry_color, const Color &edge_color){
00296 BezierMesh::Bezier_Face_Hash_T::const_iterator zt;
00297 for(zt = bezier_mesh->get_faces_begin(); zt != bezier_mesh->get_faces_end(); ++zt) {
00298 draw_bezier_triangle(*zt);
00299 }
00300
00301 BezierMesh::Bezier_Edge_Hash_T::const_iterator ze;
00302 for(ze = bezier_mesh->get_edges_begin(); ze != bezier_mesh->get_edges_end(); ++ze) {
00303 draw_bezier_edge(*ze, edge_color);
00304 }
00305
00306 BoundaryMesh::Boundary_Edge_Hash_T::const_iterator be;
00307 for(be = bdry_mesh->get_edges_begin(); be != bdry_mesh->get_edges_end(); ++be) {
00308 draw_boundary_edge(*be, bdry_color);
00309 }
00310 }
00311
00312 void Visualization::draw_data( const Color &bdry_color, const Color &edge_color, unsigned red_pos, unsigned green_pos, unsigned blue_pos){
00313 BezierMesh::Bezier_Face_Hash_T::const_iterator zt;
00314 for(zt = bezier_mesh->get_faces_begin(); zt != bezier_mesh->get_faces_end(); ++zt) {
00315 draw_bezier_triangle(*zt, red_pos, green_pos, blue_pos);
00316 }
00317
00318 BezierMesh::Bezier_Edge_Hash_T::const_iterator ze;
00319 for(ze = bezier_mesh->get_edges_begin(); ze != bezier_mesh->get_edges_end(); ++ze) {
00320 draw_bezier_edge(*ze, edge_color);
00321 }
00322
00323 BoundaryMesh::Boundary_Edge_Hash_T::const_iterator be;
00324 for(be = bdry_mesh->get_edges_begin(); be != bdry_mesh->get_edges_end(); ++be) {
00325 draw_boundary_edge(*be, bdry_color);
00326 }
00327 }
00328
00329 void Visualization::draw_debug( const Color &bdry_vert_color, const Color &bdry_edge_color, const Color &mesh_color ){
00330 BezierMesh::Bezier_Face_Hash_T::const_iterator zt;
00331 for(zt = bezier_mesh->get_faces_begin(); zt != bezier_mesh->get_faces_end(); ++zt) {
00332 draw_bezier_triangle(*zt);
00333 }
00334
00335 BezierMesh::Bezier_Edge_Hash_T::const_iterator ze;
00336 for(ze = bezier_mesh->get_edges_begin(); ze != bezier_mesh->get_edges_end(); ++ze) {
00337 draw_bezier_edge(*ze, mesh_color);
00338 }
00339
00340 glPointSize(3.0);
00341 BezierMesh::Bezier_Vertex_Hash_T::const_iterator zv;
00342 for(zv = bezier_mesh->get_vertices_begin(); zv != bezier_mesh->get_vertices_end(); ++zv) {
00343 draw_bezier_vertex(*zv, mesh_color);
00344 }
00345 glPointSize(1.0);
00346
00347 BoundaryMesh::Boundary_Edge_Hash_T::const_iterator be;
00348 for(be = bdry_mesh->get_edges_begin(); be != bdry_mesh->get_edges_end(); ++be) {
00349 draw_boundary_edge(*be, bdry_edge_color);
00350 }
00351
00352 glPointSize(3.0);
00353 BoundaryMesh::Boundary_Vertex_Hash_T::const_iterator bv;
00354 for(bv = bdry_mesh->get_vertices_begin(); bv != bdry_mesh->get_vertices_end(); ++bv) {
00355 draw_boundary_vertex(*bv, bdry_vert_color);
00356 }
00357 glPointSize(1.0);
00358 }
00359
00360 void Visualization::draw_debug( const Color &bdry_vert_color, const Color &bdry_edge_color, const Color &mesh_color, const Color &tri_color ){
00361 BezierMesh::Bezier_Face_Hash_T::const_iterator zt;
00362 for(zt = bezier_mesh->get_faces_begin(); zt != bezier_mesh->get_faces_end(); ++zt) {
00363 draw_bezier_triangle(*zt, tri_color);
00364 }
00365
00366 BezierMesh::Bezier_Edge_Hash_T::const_iterator ze;
00367 for(ze = bezier_mesh->get_edges_begin(); ze != bezier_mesh->get_edges_end(); ++ze) {
00368 draw_bezier_edge(*ze, mesh_color);
00369 }
00370
00371 glPointSize(3.0);
00372 BezierMesh::Bezier_Vertex_Hash_T::const_iterator zv;
00373 for(zv = bezier_mesh->get_vertices_begin(); zv != bezier_mesh->get_vertices_end(); ++zv) {
00374 draw_bezier_vertex(*zv, mesh_color);
00375 }
00376 glPointSize(1.0);
00377
00378 BoundaryMesh::Boundary_Edge_Hash_T::const_iterator be;
00379 for(be = bdry_mesh->get_edges_begin(); be != bdry_mesh->get_edges_end(); ++be) {
00380 draw_boundary_edge(*be, bdry_edge_color);
00381 }
00382
00383 glPointSize(3.0);
00384 BoundaryMesh::Boundary_Vertex_Hash_T::const_iterator bv;
00385 for(bv = bdry_mesh->get_vertices_begin(); bv != bdry_mesh->get_vertices_end(); ++bv) {
00386 draw_boundary_vertex(*bv, bdry_vert_color);
00387 }
00388 glPointSize(1.0);
00389 }
00390
00391 void Visualization::draw_bdry_debug( const Color &vert_color, const Color &edge_color,
00392 const Color &control_color, const Color &deboor_color)
00393 {
00394 glPointSize(1.0);
00395
00396 BoundaryMesh::Boundary_Edge_Hash_T::const_iterator be;
00397 for(be = bdry_mesh->get_edges_begin(); be != bdry_mesh->get_edges_end(); ++be) {
00398 draw_boundary_edge_debug(*be, edge_color, control_color, deboor_color);
00399 }
00400
00401 glPointSize(4.0);
00402 BoundaryMesh::Boundary_Vertex_Hash_T::const_iterator bv;
00403 for(bv = bdry_mesh->get_vertices_begin(); bv != bdry_mesh->get_vertices_end(); ++bv) {
00404 draw_boundary_vertex(*bv, vert_color);
00405 }
00406 glPointSize(1.0);
00407 }
00408
00409
00410 void Visualization::draw_skeleton( const Color &bdry_color, const Color &edge_color, bool draw_edges)
00411 {
00412 if(draw_edges){
00413 BezierMesh::Bezier_Edge_Hash_T::const_iterator ze;
00414 for(ze = bezier_mesh->get_edges_begin(); ze != bezier_mesh->get_edges_end(); ++ze) {
00415 draw_bezier_edge(*ze, edge_color);
00416 }
00417 }
00418
00419 BoundaryMesh::Boundary_Edge_Hash_T::const_iterator be;
00420 for(be = bdry_mesh->get_edges_begin(); be != bdry_mesh->get_edges_end(); ++be) {
00421 draw_boundary_edge(*be, bdry_color);
00422 }
00423 }
00424
00425 void Visualization::draw_solid( const Color &bdry_color, const Color &edge_color, bool draw_edges)
00426 {
00427 BezierMesh::Bezier_Face_Hash_T::const_iterator zt;
00428 for(zt = bezier_mesh->get_faces_begin(); zt != bezier_mesh->get_faces_end(); ++zt) {
00429 draw_bezier_triangle(*zt);
00430 }
00431
00432 if(draw_edges){
00433 BezierMesh::Bezier_Edge_Hash_T::const_iterator ze;
00434 for(ze = bezier_mesh->get_edges_begin(); ze != bezier_mesh->get_edges_end(); ++ze) {
00435 draw_bezier_edge(*ze, edge_color);
00436 }
00437 }
00438
00439 BoundaryMesh::Boundary_Edge_Hash_T::const_iterator be;
00440 for(be = bdry_mesh->get_edges_begin(); be != bdry_mesh->get_edges_end(); ++be) {
00441 draw_boundary_edge(*be, bdry_color);
00442 }
00443 }
00444
00445 void Visualization::draw_data_channel( const Color &bdry_color,
00446 const Color &edge_color,
00447 unsigned channel,
00448 double min,
00449 double max,
00450 bool draw_edges)
00451 {
00452 BezierMesh::Bezier_Face_Hash_T::const_iterator zt;
00453 for(zt = bezier_mesh->get_faces_begin(); zt != bezier_mesh->get_faces_end(); ++zt) {
00454 draw_bezier_triangle(*zt,channel, min, max);
00455 }
00456
00457 if(draw_edges){
00458 BezierMesh::Bezier_Edge_Hash_T::const_iterator ze;
00459 for(ze = bezier_mesh->get_edges_begin(); ze != bezier_mesh->get_edges_end(); ++ze) {
00460 draw_bezier_edge(*ze, edge_color);
00461 }
00462 }
00463
00464 BoundaryMesh::Boundary_Edge_Hash_T::const_iterator be;
00465 glLineWidth(3.0);
00466 for(be = bdry_mesh->get_edges_begin(); be != bdry_mesh->get_edges_end(); ++be) {
00467 draw_boundary_edge(*be, bdry_color);
00468 }
00469 glLineWidth(1.0);
00470 }
00471
00472 void Visualization::draw_point(BezierTriangle *t, double u, double v, const Color& tc, const Color &vc){
00473 draw_bezier_triangle(t, tc);
00474 Point2D pt = t->eval(u,v);
00475 draw_point(pt, vc, 5.0);
00476 }
00477
00478 void Visualization::draw_point(BezierEdge *e, double u, const Color& ec, const Color& vc){
00479 draw_bezier_edge(e, ec);
00480 Point2D pt = e->eval(u);
00481 draw_point(pt, vc, 5.0);
00482 }
00483
00484 void Visualization::draw_point(const Point2D &p, const Color &color, double size)
00485 {
00486 glPointSize(size);
00487 glColor3fv(color.v);
00488 glBegin(GL_POINTS);
00489 glVertex2dv( p.coords );
00490 glEnd();
00491 glPointSize(1.0);
00492 }
00493
00494 void Visualization::draw_circle(const Color &color, const Point2D ¢er, double radius)
00495 {
00496 int i,acc=16;
00497 double angle=0.0, inc = 2.0*PI/(double)acc;
00498 Point2D p;
00499 glColor3fv(color.v);
00500 glBegin(GL_LINE_STRIP);
00501 for(i=0; i < acc+1; i++){
00502 p.assign(center.x()+cos(angle)*radius, center.y()+sin(angle)*radius);
00503 glVertex2dv(p.coords);
00504 angle+=inc;
00505 }
00506 glEnd();
00507
00508 }
00509
00510
00511 void Visualization::draw_tuple(const BezierTuple &tup, const Color &vc, const Color &ec, const Color &fc){
00512 draw_bezier_triangle(tup.f, fc);
00513 draw_bezier_edge(tup.e, ec);
00514 glPointSize(5.0);
00515 draw_bezier_vertex(tup.v, vc);
00516 glPointSize(1.0);
00517 }
00518
00519 void Visualization::draw_boundary_vertex(BoundaryVertex *bv, const Color &color) {
00520 if( !is_visible(bv) ) return;
00521 glColor3fv(color.v);
00522 glBegin(GL_POINTS);
00523 glVertex2dv( (bv->get_cp()).coords );
00524 glEnd();
00525 }
00526
00527 void Visualization::draw_boundary_edge(const BoundaryEdge *be, const Color &c) {
00528 unsigned i,j;
00529 const QBSpline *spline = be->get_spline();
00530 glColor3fv(c.v);
00531 glBegin(GL_LINE_STRIP);
00532 for(i=0; i < ((spline->b.size()-3)/2+1); i++){
00533 for(j=0; j<=(unsigned)edge_draw_acc; j++){
00534 glVertex2dv(spline->evaluate_segment(i,double(j)/edge_draw_acc).coords);
00535 }
00536 }
00537 glEnd();
00538 }
00539
00540 void Visualization::draw_boundary_edge_debug(const BoundaryEdge *be, const Color &edge,
00541 const Color &control, const Color &deboor)
00542 {
00543 unsigned i,j;
00544 const QBSpline *spline = be->get_spline();
00545
00546 glColor3fv(control.v);
00547 glBegin(GL_LINE_STRIP);
00548 for(i=0; i < (unsigned)spline->get_num_deboor(); i++){
00549 glVertex2dv(spline->get_deboor(i)->coords);
00550 }
00551 glEnd();
00552
00553
00554 glColor3fv(edge.v);
00555 glLineWidth(2.0);
00556 glBegin(GL_LINE_STRIP);
00557 for(i=0; i < ((spline->b.size()-3)/2+1); i++){
00558 for(j=0; j<=(unsigned)edge_draw_acc; j++){
00559 glVertex2dv(spline->evaluate_segment(i,double(j)/edge_draw_acc).coords);
00560 }
00561 }
00562 glEnd();
00563 glLineWidth(1.0);
00564
00565
00566 glColor3fv(deboor.v);
00567 glPointSize(4.0);
00568 glBegin(GL_POINTS);
00569 for(i=1; i< (unsigned)spline->get_num_deboor()-1; i++){
00570 glVertex2dv( spline->get_deboor(i)->coords );
00571 }
00572 glEnd();
00573 glPointSize(1.0);
00574
00575 }
00576
00577 void Visualization::draw_bezier_vertex(BezierVertex *zv, const Color &c){
00578 if(!is_visible(zv)) return;
00579 glColor3fv(c.v);
00580 glBegin(GL_POINTS);
00581 glVertex2dv( zv->get_cp().coords );
00582 glEnd();
00583 }
00584
00585 void Visualization::draw_bezier_edge(BezierEdge *ze, const Color& c) {
00586 if( !is_visible(ze) ) return;
00587 glColor3fv(c.v);
00588 glBegin(GL_LINE_STRIP);
00589 for(int i=0; i <= edge_draw_acc; i++){
00590 glVertex2dv( ze->eval(double(i)/edge_draw_acc).coords );
00591 }
00592 glEnd();
00593 }
00594
00595 void Visualization::draw_bezier_triangle(BezierTriangle *zt)
00596 {
00597 draw_bezier_triangle(zt, colormap[ zt->get_color() ]);
00598 }
00599
00600 void Visualization::draw_bezier_triangle(BezierTriangle *zt, const Color &c)
00601 {
00602 if( !is_visible(zt) ) return;
00603 double d = 1.0 / face_draw_acc;
00604 glColor3fv(c.v);
00605 glBegin(GL_TRIANGLES);
00606 int i,j;
00607 Point2D p1,p2,p3;
00608 for(i=0; i <= face_draw_acc; i++ ) {
00609 for(j=0; j+i < face_draw_acc; j++ ) {
00610 p1 = zt->eval( i*d,j*d );
00611 p2 = zt->eval( i*d, (j+1)*d );
00612 if( i < face_draw_acc ) {
00613 p3 = zt->eval( (i+1)*d, j*d );
00614 glVertex2dv( p1.coords );
00615 glVertex2dv( p2.coords );
00616 glVertex2dv( p3.coords );
00617 }
00618 if(i>0){
00619 p3 = zt->eval( (i-1)*d, (j+1)*d );
00620 glVertex2dv( p1.coords );
00621 glVertex2dv( p2.coords );
00622 glVertex2dv( p3.coords );
00623 }
00624 }
00625 }
00626 glEnd();
00627 }
00628
00629 void Visualization::draw_bezier_triangle(BezierTriangle *zt, unsigned r, unsigned g, unsigned b) {
00630 if( !is_visible(zt) ) return;
00631 double d = 1.0 / face_draw_acc;
00632 glBegin(GL_TRIANGLES);
00633 int i,j;
00634 Point2D p1,p2,p3;
00635 LinearData d1,d2,d3;
00636 for(i=0; i <= face_draw_acc; i++ ) {
00637 for(j=0; j+i < face_draw_acc; j++ ) {
00638 p1 = zt->eval( i*d,j*d );
00639 p2 = zt->eval( i*d, (j+1)*d );
00640 d1 = zt->dataeval(i*d, j*d);
00641 d2 = zt->dataeval(i*d,(j+1)*d);
00642
00643 if( i < face_draw_acc ) {
00644 p3 = zt->eval( (i+1)*d, j*d );
00645 d3 = zt->dataeval ((i+1)*d, j*d );
00646 glColor3f(d1[r],d1[g],d1[b]);
00647 glVertex2dv( p1.coords );
00648 glColor3f(d2[r],d2[g],d2[b]);
00649 glVertex2dv( p2.coords );
00650 glColor3f(d3[r],d3[g],d3[b]);
00651 glVertex2dv( p3.coords );
00652 }
00653 if(i>0){
00654 p3 = zt->eval( (i-1)*d, (j+1)*d );
00655 d3 = zt->dataeval( (i-1)*d, (j+1)*d );
00656 glColor3f(d1[r],d1[g],d1[b]);
00657 glVertex2dv( p1.coords );
00658 glColor3f(d2[r],d2[g],d2[b]);
00659 glVertex2dv( p2.coords );
00660 glColor3f(d3[r],d3[g],d3[b]);
00661 glVertex2dv( p3.coords );
00662 }
00663 }
00664 }
00665 glEnd();
00666 }
00667
00668 void Visualization::draw_bezier_triangle(BezierTriangle *zt, unsigned channel, double min, double max)
00669 {
00670 if( !is_visible(zt) ) return;
00671 double d = 1.0 / face_draw_acc;
00672 glBegin(GL_TRIANGLES);
00673 int i,j;
00674
00675 Point2D p1,p2,p3;
00676 LinearData d1,d2,d3;
00677 for(i=0; i <= face_draw_acc; i++ ) {
00678 for(j=0; j+i < face_draw_acc; j++ ) {
00679 p1 = zt->eval( i*d,j*d );
00680 p2 = zt->eval( i*d, (j+1)*d );
00681 d1 = zt->dataeval(i*d, j*d);
00682 d2 = zt->dataeval(i*d,(j+1)*d);
00683
00684 if( i < face_draw_acc ) {
00685 p3 = zt->eval( (i+1)*d, j*d );
00686 d3 = zt->dataeval ((i+1)*d, j*d );
00687
00688 glColor3fv( spectrum_color(d1[channel], min, max).v );
00689 glVertex2dv( p1.coords );
00690
00691 glColor3fv( spectrum_color(d2[channel], min, max).v );
00692 glVertex2dv( p2.coords );
00693
00694 glColor3fv( spectrum_color(d3[channel], min, max).v );
00695 glVertex2dv( p3.coords );
00696 }
00697 if(i>0){
00698 p3 = zt->eval( (i-1)*d, (j+1)*d );
00699 d3 = zt->dataeval( (i-1)*d, (j+1)*d );
00700
00701 glColor3fv( spectrum_color(d1[channel], min, max).v );
00702 glVertex2dv( p1.coords );
00703
00704 glColor3fv( spectrum_color(d2[channel], min, max).v );
00705 glVertex2dv( p2.coords );
00706
00707 glColor3fv( spectrum_color(d3[channel], min, max).v );
00708 glVertex2dv( p3.coords );
00709 }
00710 }
00711 }
00712 glEnd();
00713 }
00714
00715
00716 void Visualization::draw_control_net(BezierTriangle *t, const Color &color)
00717 {
00718 if( !is_visible(t) ) return;
00719 glColor3fv(color.v);
00720
00721
00722 glBegin(GL_LINE_STRIP);
00723 glVertex2dv( t->get_cp(0).coords );
00724 glVertex2dv( t->get_cp(3).coords );
00725 glVertex2dv( t->get_cp(5).coords );
00726 glVertex2dv( t->get_cp(4).coords );
00727 glVertex2dv( t->get_cp(2).coords );
00728 glVertex2dv( t->get_cp(1).coords );
00729 glVertex2dv( t->get_cp(0).coords );
00730 glEnd();
00731
00732
00733 glBegin(GL_LINE_STRIP);
00734 glVertex2dv( t->get_cp(1).coords );
00735 glVertex2dv( t->get_cp(3).coords );
00736 glVertex2dv( t->get_cp(4).coords );
00737 glVertex2dv( t->get_cp(1).coords );
00738 glEnd();
00739 }
00740
00741 void Visualization::draw_polygon(Point2D ps[], int len, const Color &color)
00742 {
00743 glColor3fv(color.v);
00744 glBegin(GL_LINE_STRIP);
00745 for(int i=0; i< len; ++i) glVertex2dv( ps[i].coords );
00746 glVertex2dv( ps[0].coords );
00747 glEnd();
00748 }
00749
00750 void Visualization::draw_flip_debug(BezierEdge *e, Point2D ps[], const Point2D &primary, const Point2D & secondary)
00751 {
00752 draw_smooth_debug(e,ps,primary,secondary);
00753 }
00754
00755 void Visualization::draw_smooth_debug(BezierEdge *e, Point2D ps[], const Point2D &primary, const Point2D & secondary)
00756 {
00757 Point2D top, bot;
00758 BezierTriangle* t[2];
00759 assert(e->num_faces() == 2);
00760 t[0] = *e->begin_faces();
00761 t[1] = *++e->begin_faces();
00762
00763 get_bbox(t,2,top,bot);
00764 zoomin(top,bot);
00765 draw_bezier_triangle(t[0], DIMYELLOW);
00766 draw_bezier_triangle(t[1], DIMCYAN);
00767 draw( BLUE, GREEN );
00768 glLineWidth(4.0);
00769 draw_control_net(t[0], YELLOW);
00770 draw_control_net(t[1], CYAN);
00771 glLineWidth(2.0);
00772 draw_polygon(ps, 6, RED);
00773 glLineWidth(1.0);
00774 draw_point(primary, MAGENTA, 7.0);
00775 draw_point(secondary, DARKRED, 7.0);
00776
00777 }
00778
00785 void Visualization::resize(int _screen_width, int _screen_height)
00786 {
00787 screen_width = _screen_width;
00788 screen_height = _screen_height;
00789 screen_ratio = (double) screen_width / (double) screen_height;
00790 project();
00791 }
00792
00799 void Visualization::compute_world_size( )
00800 {
00801 world_top.assign(-1E6, -1E6);
00802 world_bot.assign(1E6,1E6);
00803 bdry_mesh->bbox( world_top, world_bot );
00804
00805 if( (world_top.x() <= world_bot.x() ) || (world_top.y() <= world_bot.y() ) ){
00806 cout<<"Visualization --- received mesh with bad width or height!"<<endl;
00807 cout<<"World top: "<<world_top<<" World bot: "<<world_bot<<endl;
00808 exit(-1);
00809 }
00810
00811 world_width = world_top.x() - world_bot.x();
00812 world_height = world_top.y() - world_bot.y();
00813
00814 double x_border = world_width/100.0;
00815 double y_border = world_height/100.0;
00816 world_top.coords[0] += x_border;
00817 world_top.coords[1] += y_border;
00818 world_bot.coords[0] -= x_border;
00819 world_bot.coords[1] -= y_border;
00820
00821 world_width = world_top.x() - world_bot.x();
00822 world_height = world_top.y() - world_bot.y();
00823 world_ratio = world_width/world_height;
00824 world_center.coords[0] = world_bot.x() + world_width * 0.5;
00825 world_center.coords[1] = world_bot.y() + world_height * 0.5;
00826 }
00827
00838 void Visualization::project()
00839 {
00840 glViewport(0, 0, screen_width, screen_height);
00841 glMatrixMode( GL_PROJECTION );
00842 glLoadIdentity();
00843
00844 compute_world_size();
00845
00846 double new_x, new_y;
00847 Point2D image_top, image_bot, image_center;
00848 double image_ratio, image_width, image_height;
00849
00850
00851
00852
00853
00854 if(zoomed){
00855 new_x = zoom_height * world_ratio * 0.5;
00856 image_top.assign(zoom_top.x()-new_x, zoom_top.y());
00857 image_bot.assign(zoom_bot.x()+new_x, zoom_bot.y());
00858
00859 image_width = image_top.x() - image_bot.x();
00860 image_height = image_top.y() - image_bot.y();
00861 image_ratio = image_width / image_height;
00862 image_center.coords[0] = image_bot.x() + image_width * 0.5;
00863 image_center.coords[1] = image_bot.y() + image_height * 0.5;
00864
00865 }
00866 else{
00867 image_ratio = world_ratio;
00868 image_width = world_width;
00869 image_height = world_height;
00870 image_top = world_top;
00871 image_bot = world_bot;
00872 image_center = world_center;
00873 }
00874
00875
00876 if(image_ratio > screen_ratio){
00877 new_y = image_width * (1.0 / screen_ratio) * 0.5;
00878 view_top.assign(image_top.x(), image_center.y() + new_y);
00879 view_bot.assign(image_bot.x(), image_center.y() - new_y);
00880 }
00881 else{
00882 new_x = image_height * screen_ratio * 0.5;
00883 view_top.assign(image_center.x() + new_x, image_top.y());
00884 view_bot.assign(image_center.x() - new_x, image_bot.y());
00885 }
00886
00887
00888
00889
00890 gluOrtho2D(view_bot.x(), view_top.x(), view_bot.y(), view_top.y());
00891 pixel_area = fabs((view_top.x() - view_bot.x()) * (view_top.y() - view_bot.y())) / (screen_width * screen_height);
00892 }
00893
00894 void Visualization::init_zoom() {
00895 zoomed = false;
00896 }
00897
00898 void Visualization::zoomin(Point2D zt, Point2D zb) {
00899 zoomed=true;
00900 zoom_top = zt;
00901 zoom_bot = zb;
00902 zoom_height = zoom_top.y() - zoom_bot.y();
00903 zoom_width = zoom_top.x() - zoom_bot.x();
00904 zoom_center.coords[0] = zoom_bot.x() + zoom_width * 0.5;
00905 zoom_center.coords[1] = zoom_bot.y() + zoom_height * 0.5;
00906 zoom_ratio = zoom_width/zoom_height;
00907 project();
00908 }
00909
00910 void Visualization::zoomout(){
00911 zoomed=false;
00912 project();
00913 }
00914
00915 Point2D Visualization::convert_from_screen_coords(int x, int y){
00916 Point2D p;
00917 p.coords[0] = double(x) * ((view_top.x() - view_bot.x())/(double)screen_width) + view_bot.x();
00918 p.coords[1] = double(screen_height - y) * ((view_top.y() - view_bot.y())/(double)screen_height) + view_bot.y();
00919 return p;
00920 }
00921
00922 void Visualization::get_bbox(BezierTriangle* t[], int num, Point2D &top, Point2D &bot)
00923 {
00924 int i,j;
00925 Point2D p;
00926 for(i=0; i<num; i++){
00927 for(j=0; j<6; j++){
00928 p = t[i]->get_cp(j);
00929 if(i==0 && j==0) {
00930 bot=p;
00931 top=p;
00932 }
00933 if(p.x() < bot.x()) bot.coords[0]=p.x();
00934 if(p.x() > top.x()) top.coords[0]=p.x();
00935 if(p.y() < bot.y()) bot.coords[1]=p.y();
00936 if(p.y() > top.y()) top.coords[1]=p.y();
00937 }
00938 }
00939 }
00940
00945 bool Visualization::is_visible(const Point2D &p)
00946 {
00947 return (p.x() >= view_bot.x()) && (p.x() <= view_top.x()) &&
00948 (p.y() >= view_bot.y()) && (p.y() <= view_top.y());
00949 }
00950
00955 bool Visualization::is_visible(const BoundaryVertex *v)
00956 {
00957 return is_visible(v->get_cp());
00958 }
00959
00964 bool Visualization::is_visible(const BezierVertex *v)
00965 {
00966 return is_visible(v->get_cp());
00967 }
00968
00973 bool Visualization::is_visible(const BezierEdge *e)
00974 {
00975 return is_visible(e->get_cp(0))
00976 || is_visible(e->get_cp(1)) || is_visible(e->get_cp(2));
00977 }
00978
00988 bool Visualization::is_visible(const BezierTriangle *t)
00989 {
00990 Point2D cps[6];
00991 int i;
00992 for(i=0; i<6; i++) cps[i] = t->get_cp(i);
00993
00994 bool on_screen = is_visible(cps[0]) || is_visible(cps[1]) || is_visible(cps[2]) ||
00995 is_visible(cps[3]) || is_visible(cps[4]) || is_visible(cps[5]);
00996 if(!on_screen) return false;
00997
00998 #ifndef DRAW_SMALL_TRIS
00999
01000 double minx=cps[0].x(), maxx=cps[0].x(), miny=cps[0].y(), maxy=cps[0].y();
01001
01002 for(i=1; i<6; i++){
01003 if( cps[i].x() < minx ) minx = cps[i].x();
01004 if( cps[i].x() > maxx ) maxx = cps[i].x();
01005 if( cps[i].y() < miny ) miny = cps[i].y();
01006 if( cps[i].y() > maxy ) maxy = cps[i].y();
01007 }
01008 double tri_area = (maxx-minx) * (maxy-miny);
01009 if( tri_area < 3*pixel_area) return false;
01010 #endif
01011
01012 return true;
01013 }
01014
01015
01016 void Visualization::start_draw()
01017 {
01018 glutSwapBuffers();
01019 glClear(GL_COLOR_BUFFER_BIT);
01020 glutSwapBuffers();
01021 glFlush();
01022 }
01023
01024 void Visualization::finish_draw()
01025 {
01026 glutSwapBuffers();
01027 glFlush();
01028 }
01029
01030 void Visualization::visual_switch(int snum, BezierTuple &tup)
01031 {
01032 glClear(GL_COLOR_BUFFER_BIT);
01033
01034 draw(GREEN, BLUE);
01035 tup = bezier_mesh->Switch(snum,tup);
01036 draw_tuple(tup,RED,WHITE,GRAY2);
01037 glFlush();
01038 }
01039
01044 BezierTuple Visualization::visual_locate(Point2D pt)
01045 {
01046 BezierTuple tup;
01047 double u,v;
01048 int cd;
01049
01050 cd = bezier_mesh->blind_locate_point(pt, tup, u, v);
01051 draw_point(pt, GREEN, 5.0);
01052 switch(cd) {
01053 case 0:
01054 draw_point(pt, RED, 5.0);
01055 break;
01056 case 1:
01057 draw_point(tup.e, u, YELLOW, RED);
01058 break;
01059 case 2:
01060 draw_point(tup.f, u, v, YELLOW, RED);
01061 break;
01062 default:
01063 cerr << "pointlocation error: returned " << cd << endl;
01064 tup = bezier_mesh->get_tuple();
01065 }
01066 return tup;
01067 }
01068
01069 #if 0
01070 double Simulation::get_jacobian(BezierTriangle *t, Point2D p){
01071 double u,v;
01072 if( ! t->newton_find(p,u,v)){
01073 cout<<"Simulation::get_jacobian - newton find failure"<<endl;
01074 return 0.0;
01075 }
01076 return t->jacobian(u,v);
01077 }
01078
01079 void Simulation::check_for_inversions(){
01080 int num_inversions=0;
01081 glClear( GL_COLOR_BUFFER_BIT );
01082 glLineWidth(1.0);
01083 draw_debug(RED,GREEN,BLUE);
01084 BezierMesh::Bezier_Face_Hash_T::iterator i;
01085 for(i = bezier_mesh->get_faces_begin(); i != bezier_mesh->get_faces_end(); ++i){
01086 if( (*i)->is_inverted()) {
01087 (*i)->draw(RED);
01088 num_inversions++;
01089
01090 }
01091 }
01092 glFlush();
01093 cout<<"Found "<<num_inversions<<" Inversions"<<endl;
01094 }
01095
01096 void Simulation::draw_troubled_triangles(BezierTriangle *t1, BezierTriangle *t2, Point2D pt, Point2D *poly){
01097 Point2D top, bot, p;
01098 int i,j;
01099 BezierTriangle *t;
01100 BezierEdge *e;
01101
01102 bot=top=*t1->cp[0];
01103 for(i=0; i<2; i++){
01104 if(i==0) t= t1;
01105 else t=t2;
01106
01107 for(j=0; j<6; j++){
01108 p=*t->cp[j];
01109 if(p.x() < bot.x()) bot.coords[0]=p.x();
01110 if(p.x() > top.x()) top.coords[0]=p.x();
01111 if(p.y() < bot.y()) bot.coords[1]=p.y();
01112 if(p.y() > top.y()) top.coords[1]=p.y();
01113 }
01114 }
01115 double world_width = top.x() - bot.x();
01116 double world_height = top.y() - bot.y();
01117 double x_border = world_width/100.0;
01118 double y_border = world_height/100.0;
01119 top.coords[0] += x_border;
01120 top.coords[1] += y_border;
01121 bot.coords[0] -= x_border;
01122 bot.coords[1] -= y_border;
01123 world_width = top.x() - bot.x();
01124 world_height = top.y() - bot.y();
01125 double screen_ratio = (double) screen_width / (double) screen_height;
01126 double world_ratio=world_width/world_height;
01127 double y_center = bot.y()+(top.y() - bot.y()) /2.0;
01128 double x_center = bot.x()+(top.x() - bot.x()) /2.0;
01129
01130 if(world_ratio > screen_ratio){
01131 double new_y=world_width*(1/screen_ratio)*0.5;
01132 top.assign(top.x(), y_center+new_y);
01133 bot.assign(bot.x(), y_center-new_y);
01134 }
01135 else{
01136 double new_x = world_height * screen_ratio * 0.5;
01137 top.assign(x_center+new_x, top.y());
01138 bot.assign(x_center-new_x, bot.y());
01139 }
01140 glClear( GL_COLOR_BUFFER_BIT );
01141 glLineWidth(1.0);
01142 draw_debug(RED,BLUE,GREEN);
01143
01144 glLineWidth(3.0);
01145 for(i=0; i<2; i++){
01146 if(i==0) t= t1;
01147 else t=t2;
01148
01149 for(j=0; j<3; j++){
01150 e=(BezierEdge*) t->edges[j];
01151 e->draw(RED);
01152 }
01153 }
01154 glColor3f(MAGENTA.R,MAGENTA.G,MAGENTA.B);
01155 glPointSize(6.0);
01156 glBegin(GL_POINTS);
01157 glVertex2dv( pt.coords );
01158 glEnd();
01159 glFlush();
01160 cout<<"Enconutered mesh geometry error!!! Bad triangles drawn in red"<<endl;
01161 cout<<"press <enter> to zoom in on problem"<<endl;
01162
01163 getchar();
01164
01165
01166
01167 glViewport(0,0,screen_width,screen_height);
01168 glMatrixMode( GL_PROJECTION );
01169 glLoadIdentity();
01170
01171 gluOrtho2D(bot.x(), top.x(), bot.y(), top.y());
01172 glClear( GL_COLOR_BUFFER_BIT );
01173 glLineWidth(1.0);
01174 draw_debug(RED,BLUE,GREEN);
01175 glLineWidth(3.0);
01176 for(i=0; i<2; i++){
01177 if(i==0) t= t1;
01178 else t=t2;
01179
01180 for(j=0; j<3; j++){
01181 e=(BezierEdge*) t->edges[j];
01182 e->draw(RED);
01183 }
01184 }
01185 glColor3f(MAGENTA.R,MAGENTA.G,MAGENTA.B);
01186 glPointSize(6.0);
01187 glBegin(GL_POINTS);
01188 glVertex2dv( pt.coords );
01189 glEnd();
01190
01191 glBegin(GL_LINE_STRIP);
01192 glColor3f(YELLOW.R,YELLOW.G,YELLOW.B);
01193 glLineWidth(2.0);
01194 for(i=0; i<6; i++) {
01195 glVertex2dv( poly[i].coords);
01196 }
01197 glVertex2dv( poly[0].coords);
01198 glEnd();
01199 glFlush();
01200 cout<<"Zoomed view of problem"<<endl;
01201 cout<<"press <enter> to continue meshing"<<endl;
01202 getchar();
01203
01204
01205 project_to_screen(screen_width, screen_height);
01206 glClear( GL_COLOR_BUFFER_BIT );
01207 glLineWidth(1.0);
01208 draw_debug(RED,BLUE,GREEN);
01209 glFlush();
01210 }
01211
01212 void Simulation::draw_troubled_interp_triangles(BezierTriangle *t1, GhostTriangle **oldts, Point2D pt){
01213 Point2D top, bot, p;
01214 int i,j;
01215 GhostTriangle *t;
01216 BezierEdge *e;
01217
01218 bot=top=*t1->cp[0];
01219 for(i=0; i<2; i++){
01220 if(i==0) t = oldts[0];
01221 else t = oldts[1];
01222
01223 for(j=0; j<6; j++){
01224 p = t->cp[j];
01225 if(p.x() < bot.x()) bot.coords[0]=p.x();
01226 if(p.x() > top.x()) top.coords[0]=p.x();
01227 if(p.y() < bot.y()) bot.coords[1]=p.y();
01228 if(p.y() > top.y()) top.coords[1]=p.y();
01229 }
01230 }
01231 double world_width = top.x() - bot.x();
01232 double world_height = top.y() - bot.y();
01233 double x_border = world_width/100.0;
01234 double y_border = world_height/100.0;
01235 top.coords[0] += x_border;
01236 top.coords[1] += y_border;
01237 bot.coords[0] -= x_border;
01238 bot.coords[1] -= y_border;
01239 world_width = top.x() - bot.x();
01240 world_height = top.y() - bot.y();
01241 double screen_ratio = (double) screen_width / (double) screen_height;
01242 double world_ratio=world_width/world_height;
01243 double y_center = bot.y()+(top.y() - bot.y()) /2.0;
01244 double x_center = bot.x()+(top.x() - bot.x()) /2.0;
01245
01246 if(world_ratio > screen_ratio){
01247 double new_y=world_width*(1/screen_ratio)*0.5;
01248 top.assign(top.x(), y_center+new_y);
01249 bot.assign(bot.x(), y_center-new_y);
01250 }
01251 else{
01252 double new_x = world_height * screen_ratio * 0.5;
01253 top.assign(x_center+new_x, top.y());
01254 bot.assign(x_center-new_x, bot.y());
01255 }
01256 glClear( GL_COLOR_BUFFER_BIT );
01257 glLineWidth(1.0);
01258 draw_debug(RED,BLUE,GREEN);
01259
01260
01261 glLineWidth(4.0);
01262 glColor3f(RED.R, RED.G, RED.B);
01263 double u;
01264 for(j=0; j<2; j++){
01265 t = oldts[j];
01266
01267 glBegin(GL_LINE_STRIP);
01268 for(int i=0; i <= edge_draw_acc; i++){
01269 u=double(i)/edge_draw_acc;
01270 glVertex2dv( t->eval(u,0).coords );
01271 }
01272 glEnd();
01273
01274
01275 glBegin(GL_LINE_STRIP);
01276 for(int i=0; i <= edge_draw_acc; i++){
01277 u=double(i)/edge_draw_acc;
01278 glVertex2dv( t->eval(0,u).coords );
01279 }
01280 glEnd();
01281
01282
01283 glBegin(GL_LINE_STRIP);
01284 for(int i=0; i <= edge_draw_acc; i++){
01285 u=double(i)/edge_draw_acc;
01286 glVertex2dv( t->eval(u,1-u).coords );
01287 }
01288 glEnd();
01289 }
01290
01291 glLineWidth(2.0);
01292 for(j=0; j<3; j++){
01293 e=(BezierEdge*) t1->edges[j];
01294 e->draw(CYAN);
01295 }
01296 glColor3f(MAGENTA.R,MAGENTA.G,MAGENTA.B);
01297 glPointSize(6.0);
01298 glBegin(GL_POINTS);
01299 glVertex2dv( pt.coords );
01300 glEnd();
01301 glFlush();
01302 cout<<"Enconutered mesh geometry error!!! Bad triangles drawn in red"<<endl;
01303 cout<<"press <enter> to zoom in on problem"<<endl;
01304
01305 getchar();
01306
01307
01308
01309 glViewport(0,0,screen_width,screen_height);
01310 glMatrixMode( GL_PROJECTION );
01311 glLoadIdentity();
01312
01313 gluOrtho2D(bot.x(), top.x(), bot.y(), top.y());
01314 glClear( GL_COLOR_BUFFER_BIT );
01315 glLineWidth(0.5);
01316 draw_debug(RED,BLUE,GREEN);
01317
01318
01319 glLineWidth(5.0);
01320 glColor3f(RED.R, RED.G, RED.B);
01321 for(j=0; j<2; j++){
01322 t = oldts[j];
01323
01324 glBegin(GL_LINE_STRIP);
01325 for(int i=0; i <= edge_draw_acc; i++){
01326 u=double(i)/edge_draw_acc;
01327 glVertex2dv( t->eval(u,0).coords );
01328 }
01329 glEnd();
01330
01331
01332 glBegin(GL_LINE_STRIP);
01333 for(int i=0; i <= edge_draw_acc; i++){
01334 u=double(i)/edge_draw_acc;
01335 glVertex2dv( t->eval(0,u).coords );
01336 }
01337 glEnd();
01338
01339
01340 glBegin(GL_LINE_STRIP);
01341 for(int i=0; i <= edge_draw_acc; i++){
01342 u=double(i)/edge_draw_acc;
01343 glVertex2dv( t->eval(u,1-u).coords );
01344 }
01345 glEnd();
01346 }
01347
01348 glLineWidth(1.0);
01349 for(j=0; j<3; j++){
01350 e=(BezierEdge*) t1->edges[j];
01351 e->draw(CYAN);
01352 }
01353 glColor3f(MAGENTA.R,MAGENTA.G,MAGENTA.B);
01354 glPointSize(6.0);
01355 glBegin(GL_POINTS);
01356 glVertex2dv( pt.coords );
01357 glEnd();
01358 glFlush();
01359 cout<<"Zoomed view of problem"<<endl;
01360 cout<<"This error occured while trying to reinteroplate after a flip"<<endl;
01361 cout<<"The red triangles are the original triangles (old triangles)"<<endl;
01362 cout<<"The cyan triangle is on of the new triangles created"<<endl;
01363 cout<<"The magenta point is the point we were sure was in the blue triangle, but were not able to lacte in either red triangle"<<endl;
01364 cout<<"press <enter> to continue meshing"<<endl;
01365 getchar();
01366
01367
01368 project_to_screen(screen_width, screen_height);
01369 glClear( GL_COLOR_BUFFER_BIT );
01370 glLineWidth(1.0);
01371 draw(BLUE,GREEN);
01372 glFlush();
01373 }
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408 #endif
01409
01410
01411 void Visualization::draw_newton(){
01412 double red,green;
01413 double u,v;
01414 double alpha,beta;
01415 Point2D pt;
01416 int newton_iterations=20;
01417 int j=0;
01418 unsigned num_calls=0, num_failures=0;
01419 timeval start, end;
01420 int niter;
01421 int edge_num;
01422 double elapsed;
01423 BezierMesh::Bezier_Face_Hash_T::iterator i;
01424
01425 glBegin(GL_POINTS);
01426 glPointSize(1.0);
01427 cout<<"$$$$$$$$Newton Convergence Map$$$$$$$$"<<endl;
01428 cout<<"Processing";
01429 cout.flush();
01430 gettimeofday(&start,NULL);
01431 for(i=bezier_mesh->get_faces_begin(); i != bezier_mesh->get_faces_end(); ++i){
01432 for(u=0; u<1.0; u+=0.025){
01433 for(v=0; v+u<1.0; v+=0.025){
01434 pt = (*i)->eval(u,v);
01435 if( (*i)->newton_find(pt, alpha, beta, niter, edge_num)){
01436 if(niter==newton_iterations){
01437 red=1.0;
01438 green=1.0;
01439 } else{
01440 green=1.0-((double)niter/newton_iterations);
01441 red=0.0;
01442 }
01443 } else {
01444 red=1.0;
01445 green=0.0;
01446 num_failures++;
01447 }
01448 glColor3f(red,green,0.0);
01449 glVertex2dv(pt.coords);
01450 num_calls++;
01451 }
01452 }
01453 if(j++ % 25==24) {cout<<"."; cout.flush(); }
01454 }
01455 gettimeofday(&end,NULL);
01456 glEnd();
01457 cout<<endl;
01458 elapsed = 1000.0 * (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec)/1000.0;
01459 cout<<"Newton calls: "<<num_calls<<" Num failures: "<<num_failures<<endl
01460 <<" total_time(sec): "<<elapsed/1000.0
01461 <<" per_call_time(ms): "<<elapsed/num_calls<<endl;
01462 }
01463
01464 void Visualization::draw_inverted_classes()
01465 {
01466 vector<BezierTriangle*> normal, inverted, unknown;
01467 bezier_mesh->classify_inverted_triangles(normal, inverted, unknown);
01468 cout<<"Inverted Classification:"<<endl;
01469 cout<<"normal: "<<normal.size()<<" inverted: "<<inverted.size()<<" unknown: "<<unknown.size()
01470 <<" errors: "<<bezier_mesh->get_num_faces() - normal.size() - inverted.size() - unknown.size()<<endl<<endl;
01471 vector<BezierTriangle*>::iterator i;
01472 for(i=normal.begin(); i!=normal.end(); ++i) draw_bezier_triangle(*i, GREEN);
01473 for(i=inverted.begin(); i!=inverted.end(); ++i) draw_bezier_triangle(*i, RED);
01474 for(i=unknown.begin(); i!=unknown.end(); ++i) draw_bezier_triangle(*i, YELLOW);
01475 }
01476
01477 int Visualization::draw_smoothable_edges()
01478 {
01479 int unsmoothable=0;
01480 for(BezierMesh::Edge_Hash_T::iterator i = bezier_mesh->get_edges_begin();
01481 i != bezier_mesh->get_edges_end(); ++i){
01482 BezierEdge *e = *i;
01483 if (e->is_boundary()){
01484 draw_bezier_edge(e, BLUE);
01485 } else {
01486 if(bezier_mesh->can_smooth(e)) draw_bezier_edge(e, GREEN);
01487 else{
01488 draw_bezier_edge(e, RED);
01489 unsmoothable++;
01490 }
01491 }
01492 }
01493 return unsmoothable;
01494 }
01495
01496 int Visualization::draw_flippable_edges()
01497 {
01498 int unflippable=0;
01499 for(BezierMesh::Edge_Hash_T::iterator i = bezier_mesh->get_edges_begin();
01500 i != bezier_mesh->get_edges_end(); ++i){
01501 BezierEdge *e = *i;
01502 if (e->is_boundary()){
01503 draw_bezier_edge(e, BLUE);
01504 } else if(bezier_mesh->should_flip(e)) {
01505 if(bezier_mesh->can_flip(e)) draw_bezier_edge(e, CYAN);
01506 else{
01507 draw_bezier_edge(e, RED);
01508 unflippable++;
01509 }
01510 } else {
01511 draw_bezier_edge(e, GREEN);
01512 }
01513 }
01514 return unflippable;
01515 }
01516
01517
01518
01519
01520