visualization.C

Go to the documentation of this file.
00001 
00007 #ifdef HAVE_CONFIG_H
00008 #include <tumble-conf.h>
00009 #endif /* HAVE_CONFIG_H */
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     /* initialize color mapping */
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 /* methods for tumble-view.rb */
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 &center, 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     /* draw control */
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     /* draw edge */
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     /* draw deboors */
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     /* draw perimiter */
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     /*craw inside triangle */
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     //cout<<"World top: "<<world_top<<"World bot: "<<world_bot<<endl;
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     /* If zoomed then adjust the zoom size to maintain same aspect ratio as the world */
00851     /* Then set the image varibles to be the new aspect corrected zoom, if zoomed,
00852      * or the normal world size if not zoomed
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         //assert( fabs(image_ratio - world_ratio) < 1E-4 );
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     /* Now given the image to display, correct to maintain aspect ratio */
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     /* With all aspect ratios maintained, and global view variables set,
00888      * now just project the image */
00889     //cout<<"View top: "<<view_top<<" View bot: "<<view_bot<<endl;
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     /* otherwise check if we are less than a pixel */
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 /* DRAW_SMALL_TRIS */
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); /* draw the searched-for point in green */
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         //(*i)->print();
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     /* redraw old screen */
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     /* draw old triangles */
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         /*draw edge 1 */
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         /*draw edge 2 */
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         /*draw edge 3 */
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     /*draw new triangle */
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     /* draw old triangles */
01319     glLineWidth(5.0);
01320     glColor3f(RED.R, RED.G, RED.B);
01321     for(j=0; j<2; j++){
01322         t = oldts[j];
01323         /*draw edge 1 */
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         /*draw edge 2 */
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         /*draw edge 3 */
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     /*draw new triangle */
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     /* redraw old screen */
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 void Simulation::visual_link(BezierTuple tup){
01382     list<BezierVertex*> link;
01383     bezier_mesh->get_link(tup,link);
01384     draw_link(link,MAGENTA,RED,GREEN);
01385 }
01386 */
01387 
01388 /*
01389 void Simulation::draw_link(list<BezierVertex*> &link, Color startc, Color midc, Color endc){
01390     list<BezierVertex*>::iterator i;
01391     if(link.size()<2){
01392         cout<<"Error link too small"<<endl;
01393         return;
01394 }
01395     glPointSize(10.0);
01396     i=link.begin();
01397     (*i)->draw(startc);
01398     glPointSize(4.0);
01399     ++i;
01400     for(; i != --link.end(); ++i){
01401         (*i)->draw(midc);
01402 }
01403     glPointSize(6.0);
01404     (*i)->draw(endc);
01405     glPointSize(1.0);
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 

Generated on Mon May 24 09:53:31 2010 for TUMBLE by  doxygen 1.5.2