00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 #include <pcl/apps/in_hand_scanner/opengl_viewer.h>
00042 
00043 #include <cmath>
00044 #include <typeinfo>
00045 #include <cstdlib>
00046 
00047 #include <pcl/pcl_config.h>
00048 #ifdef OPENGL_IS_A_FRAMEWORK
00049 # include <OpenGL/gl.h>
00050 # include <OpenGL/glu.h>
00051 #else
00052 # include <GL/gl.h>
00053 # include <GL/glu.h>
00054 #endif
00055 
00056 #include <QtOpenGL>
00057 
00058 #include <pcl/common/centroid.h>
00059 #include <pcl/common/impl/centroid.hpp> 
00060 #include <pcl/apps/in_hand_scanner/visibility_confidence.h>
00061 
00063 
00065 
00066 pcl::ihs::detail::FaceVertexMesh::FaceVertexMesh ()
00067   : vertices       (),
00068     triangles      (),
00069     transformation (Eigen::Isometry3d::Identity ())
00070 {
00071 }
00072 
00074 
00075 pcl::ihs::detail::FaceVertexMesh::FaceVertexMesh (const Mesh& mesh, const Eigen::Isometry3d& T)
00076   : vertices       (mesh.getVertexDataCloud ()),
00077     triangles      (),
00078     transformation (T)
00079 {
00080   if (typeid (Mesh::MeshTag) != typeid (pcl::geometry::TriangleMeshTag))
00081   {
00082     std::cerr << "In opengl_viewer.cpp: Only triangle meshes are currently supported!\n";
00083     exit (EXIT_FAILURE);
00084   }
00085 
00086   for (CloudIHS::iterator it=vertices.begin (); it!=vertices.end (); ++it)
00087   {
00088     std::swap (it->r, it->b);
00089   }
00090 
00091   triangles.reserve (mesh.sizeFaces ());
00092   pcl::ihs::detail::FaceVertexMesh::Triangle triangle;
00093 
00094   for (unsigned int i=0; i<mesh.sizeFaces (); ++i)
00095   {
00096     Mesh::VertexAroundFaceCirculator circ = mesh.getVertexAroundFaceCirculator (Mesh::FaceIndex (i));
00097     triangle.first  = (circ++).getTargetIndex ().get ();
00098     triangle.second = (circ++).getTargetIndex ().get ();
00099     triangle.third  = (circ  ).getTargetIndex ().get ();
00100 
00101     triangles.push_back (triangle);
00102   }
00103 }
00104 
00106 
00108 
00109 pcl::ihs::OpenGLViewer::OpenGLViewer (QWidget* parent)
00110   : QGLWidget            (parent),
00111     mutex_vis_           (),
00112     timer_vis_           (new QTimer (this)),
00113     colormap_            (Colormap::Constant (255)),
00114     vis_conf_norm_       (1),
00115     drawn_meshes_        (),
00116     mesh_representation_ (MR_POINTS),
00117     coloring_            (COL_RGB),
00118     draw_box_            (false),
00119     box_coefficients_    (),
00120     scaling_factor_      (1.),
00121     R_cam_               (1., 0., 0., 0.),
00122     t_cam_               (0., 0., 0.),
00123     cam_pivot_           (0., 0., 0.),
00124     cam_pivot_id_        (""),
00125     mouse_pressed_begin_ (false),
00126     x_prev_              (0),
00127     y_prev_              (0)
00128 {
00129   
00130   connect (timer_vis_.get (), SIGNAL (timeout ()), this, SLOT (timerCallback ()));
00131   timer_vis_->start (33);
00132 
00133   
00134   QWidget::setAutoFillBackground (false);
00135 
00136   
00137   this->setFocusPolicy (Qt::StrongFocus);
00138 
00139   
00140   qRegisterMetaType <pcl::ihs::OpenGLViewer::MeshRepresentation> ("MeshRepresentation");
00141   qRegisterMetaType <pcl::ihs::OpenGLViewer::Coloring>           ("Coloring");
00142 
00144   
00146 
00147   
00148   
00149 
00150   
00151   
00152 
00153   
00154   
00155   
00156   
00157   
00158   
00159   
00160   
00161 
00162   
00163   
00164   
00165   
00166   
00167 
00168   
00169 
00170   
00171   
00172   
00173   
00174   
00175 
00176   
00177   
00178   
00179   
00180   
00181   
00182 
00183   
00184   
00185 
00186   colormap_.col (  0) = Color (180,   0,   0);
00187   colormap_.col (  1) = Color (182,   9,   1);
00188   colormap_.col (  2) = Color (184,  17,   1);
00189   colormap_.col (  3) = Color (186,  24,   2);
00190   colormap_.col (  4) = Color (188,  29,   2);
00191   colormap_.col (  5) = Color (190,  33,   3);
00192   colormap_.col (  6) = Color (192,  38,   4);
00193   colormap_.col (  7) = Color (194,  42,   5);
00194   colormap_.col (  8) = Color (196,  46,   6);
00195   colormap_.col (  9) = Color (197,  49,   7);
00196   colormap_.col ( 10) = Color (199,  53,   9);
00197   colormap_.col ( 11) = Color (201,  56,  10);
00198   colormap_.col ( 12) = Color (203,  59,  12);
00199   colormap_.col ( 13) = Color (205,  63,  13);
00200   colormap_.col ( 14) = Color (207,  66,  15);
00201   colormap_.col ( 15) = Color (208,  69,  17);
00202   colormap_.col ( 16) = Color (210,  72,  18);
00203   colormap_.col ( 17) = Color (212,  75,  20);
00204   colormap_.col ( 18) = Color (214,  78,  21);
00205   colormap_.col ( 19) = Color (215,  81,  23);
00206   colormap_.col ( 20) = Color (217,  84,  25);
00207   colormap_.col ( 21) = Color (219,  87,  26);
00208   colormap_.col ( 22) = Color (221,  89,  28);
00209   colormap_.col ( 23) = Color (222,  92,  30);
00210   colormap_.col ( 24) = Color (224,  95,  32);
00211   colormap_.col ( 25) = Color (225,  98,  33);
00212   colormap_.col ( 26) = Color (227, 101,  35);
00213   colormap_.col ( 27) = Color (229, 103,  37);
00214   colormap_.col ( 28) = Color (230, 106,  39);
00215   colormap_.col ( 29) = Color (232, 109,  40);
00216   colormap_.col ( 30) = Color (233, 112,  42);
00217   colormap_.col ( 31) = Color (235, 114,  44);
00218   colormap_.col ( 32) = Color (236, 117,  46);
00219   colormap_.col ( 33) = Color (238, 120,  48);
00220   colormap_.col ( 34) = Color (239, 122,  50);
00221   colormap_.col ( 35) = Color (241, 125,  52);
00222   colormap_.col ( 36) = Color (242, 127,  54);
00223   colormap_.col ( 37) = Color (244, 130,  56);
00224   colormap_.col ( 38) = Color (245, 133,  58);
00225   colormap_.col ( 39) = Color (246, 135,  60);
00226   colormap_.col ( 40) = Color (248, 138,  62);
00227   colormap_.col ( 41) = Color (249, 140,  64);
00228   colormap_.col ( 42) = Color (250, 143,  66);
00229   colormap_.col ( 43) = Color (252, 145,  68);
00230   colormap_.col ( 44) = Color (253, 148,  70);
00231   colormap_.col ( 45) = Color (254, 150,  73);
00232   colormap_.col ( 46) = Color (255, 153,  75);
00233   colormap_.col ( 47) = Color (255, 154,  76);
00234   colormap_.col ( 48) = Color (255, 156,  78);
00235   colormap_.col ( 49) = Color (255, 158,  80);
00236   colormap_.col ( 50) = Color (255, 159,  82);
00237   colormap_.col ( 51) = Color (255, 161,  84);
00238   colormap_.col ( 52) = Color (255, 163,  86);
00239   colormap_.col ( 53) = Color (255, 164,  88);
00240   colormap_.col ( 54) = Color (255, 166,  90);
00241   colormap_.col ( 55) = Color (255, 168,  92);
00242   colormap_.col ( 56) = Color (255, 169,  93);
00243   colormap_.col ( 57) = Color (255, 171,  95);
00244   colormap_.col ( 58) = Color (255, 172,  97);
00245   colormap_.col ( 59) = Color (255, 174,  99);
00246   colormap_.col ( 60) = Color (255, 176, 101);
00247   colormap_.col ( 61) = Color (255, 177, 103);
00248   colormap_.col ( 62) = Color (255, 179, 105);
00249   colormap_.col ( 63) = Color (255, 180, 107);
00250   colormap_.col ( 64) = Color (255, 182, 109);
00251   colormap_.col ( 65) = Color (255, 183, 111);
00252   colormap_.col ( 66) = Color (255, 185, 113);
00253   colormap_.col ( 67) = Color (255, 186, 115);
00254   colormap_.col ( 68) = Color (255, 188, 117);
00255   colormap_.col ( 69) = Color (255, 189, 119);
00256   colormap_.col ( 70) = Color (255, 191, 122);
00257   colormap_.col ( 71) = Color (255, 192, 124);
00258   colormap_.col ( 72) = Color (255, 194, 126);
00259   colormap_.col ( 73) = Color (255, 195, 128);
00260   colormap_.col ( 74) = Color (255, 196, 130);
00261   colormap_.col ( 75) = Color (255, 198, 132);
00262   colormap_.col ( 76) = Color (255, 199, 134);
00263   colormap_.col ( 77) = Color (255, 201, 136);
00264   colormap_.col ( 78) = Color (255, 202, 139);
00265   colormap_.col ( 79) = Color (255, 203, 141);
00266   colormap_.col ( 80) = Color (255, 205, 143);
00267   colormap_.col ( 81) = Color (255, 206, 145);
00268   colormap_.col ( 82) = Color (255, 207, 147);
00269   colormap_.col ( 83) = Color (255, 209, 149);
00270   colormap_.col ( 84) = Color (255, 210, 152);
00271   colormap_.col ( 85) = Color (255, 211, 154);
00272   colormap_.col ( 86) = Color (255, 213, 156);
00273   colormap_.col ( 87) = Color (255, 214, 158);
00274   colormap_.col ( 88) = Color (255, 215, 161);
00275   colormap_.col ( 89) = Color (255, 216, 163);
00276   colormap_.col ( 90) = Color (255, 218, 165);
00277   colormap_.col ( 91) = Color (255, 219, 168);
00278   colormap_.col ( 92) = Color (255, 220, 170);
00279   colormap_.col ( 93) = Color (255, 221, 172);
00280   colormap_.col ( 94) = Color (255, 223, 175);
00281   colormap_.col ( 95) = Color (255, 224, 177);
00282   colormap_.col ( 96) = Color (255, 225, 179);
00283   colormap_.col ( 97) = Color (255, 226, 182);
00284   colormap_.col ( 98) = Color (255, 227, 184);
00285   colormap_.col ( 99) = Color (255, 228, 186);
00286   colormap_.col (100) = Color (255, 230, 189);
00287   colormap_.col (101) = Color (255, 231, 191);
00288   colormap_.col (102) = Color (255, 232, 193);
00289   colormap_.col (103) = Color (255, 233, 196);
00290   colormap_.col (104) = Color (255, 234, 198);
00291   colormap_.col (105) = Color (255, 235, 201);
00292   colormap_.col (106) = Color (255, 236, 203);
00293   colormap_.col (107) = Color (255, 237, 205);
00294   colormap_.col (108) = Color (255, 238, 208);
00295   colormap_.col (109) = Color (255, 239, 210);
00296   colormap_.col (110) = Color (255, 240, 213);
00297   colormap_.col (111) = Color (255, 241, 215);
00298   colormap_.col (112) = Color (255, 242, 218);
00299   colormap_.col (113) = Color (255, 243, 220);
00300   colormap_.col (114) = Color (255, 244, 222);
00301   colormap_.col (115) = Color (255, 245, 225);
00302   colormap_.col (116) = Color (255, 246, 227);
00303   colormap_.col (117) = Color (255, 247, 230);
00304   colormap_.col (118) = Color (255, 248, 232);
00305   colormap_.col (119) = Color (255, 249, 235);
00306   colormap_.col (120) = Color (255, 249, 237);
00307   colormap_.col (121) = Color (255, 250, 239);
00308   colormap_.col (122) = Color (255, 251, 242);
00309   colormap_.col (123) = Color (255, 252, 244);
00310   colormap_.col (124) = Color (255, 253, 247);
00311   colormap_.col (125) = Color (255, 253, 249);
00312   colormap_.col (126) = Color (255, 254, 251);
00313   colormap_.col (127) = Color (255, 255, 254);
00314   colormap_.col (128) = Color (255, 255, 254);
00315   colormap_.col (129) = Color (254, 255, 253);
00316   colormap_.col (130) = Color (253, 255, 252);
00317   colormap_.col (131) = Color (252, 255, 250);
00318   colormap_.col (132) = Color (251, 255, 249);
00319   colormap_.col (133) = Color (250, 255, 248);
00320   colormap_.col (134) = Color (249, 255, 246);
00321   colormap_.col (135) = Color (248, 255, 245);
00322   colormap_.col (136) = Color (247, 255, 244);
00323   colormap_.col (137) = Color (246, 255, 242);
00324   colormap_.col (138) = Color (245, 255, 241);
00325   colormap_.col (139) = Color (244, 255, 240);
00326   colormap_.col (140) = Color (243, 255, 238);
00327   colormap_.col (141) = Color (242, 255, 237);
00328   colormap_.col (142) = Color (241, 255, 236);
00329   colormap_.col (143) = Color (240, 255, 235);
00330   colormap_.col (144) = Color (239, 255, 233);
00331   colormap_.col (145) = Color (238, 255, 232);
00332   colormap_.col (146) = Color (237, 255, 231);
00333   colormap_.col (147) = Color (236, 255, 229);
00334   colormap_.col (148) = Color (235, 255, 228);
00335   colormap_.col (149) = Color (234, 255, 227);
00336   colormap_.col (150) = Color (234, 255, 225);
00337   colormap_.col (151) = Color (233, 255, 224);
00338   colormap_.col (152) = Color (232, 255, 223);
00339   colormap_.col (153) = Color (231, 255, 221);
00340   colormap_.col (154) = Color (230, 255, 220);
00341   colormap_.col (155) = Color (229, 255, 219);
00342   colormap_.col (156) = Color (228, 255, 218);
00343   colormap_.col (157) = Color (227, 255, 216);
00344   colormap_.col (158) = Color (226, 255, 215);
00345   colormap_.col (159) = Color (225, 255, 214);
00346   colormap_.col (160) = Color (224, 255, 212);
00347   colormap_.col (161) = Color (223, 255, 211);
00348   colormap_.col (162) = Color (222, 255, 210);
00349   colormap_.col (163) = Color (221, 255, 208);
00350   colormap_.col (164) = Color (220, 255, 207);
00351   colormap_.col (165) = Color (219, 255, 206);
00352   colormap_.col (166) = Color (218, 255, 204);
00353   colormap_.col (167) = Color (217, 255, 203);
00354   colormap_.col (168) = Color (216, 255, 202);
00355   colormap_.col (169) = Color (215, 255, 201);
00356   colormap_.col (170) = Color (214, 255, 199);
00357   colormap_.col (171) = Color (213, 255, 198);
00358   colormap_.col (172) = Color (211, 255, 197);
00359   colormap_.col (173) = Color (210, 255, 195);
00360   colormap_.col (174) = Color (209, 255, 194);
00361   colormap_.col (175) = Color (208, 255, 193);
00362   colormap_.col (176) = Color (207, 255, 191);
00363   colormap_.col (177) = Color (206, 255, 190);
00364   colormap_.col (178) = Color (205, 255, 188);
00365   colormap_.col (179) = Color (204, 255, 187);
00366   colormap_.col (180) = Color (203, 255, 186);
00367   colormap_.col (181) = Color (202, 255, 184);
00368   colormap_.col (182) = Color (201, 255, 183);
00369   colormap_.col (183) = Color (199, 255, 182);
00370   colormap_.col (184) = Color (198, 255, 180);
00371   colormap_.col (185) = Color (197, 255, 179);
00372   colormap_.col (186) = Color (196, 255, 177);
00373   colormap_.col (187) = Color (195, 255, 176);
00374   colormap_.col (188) = Color (194, 255, 174);
00375   colormap_.col (189) = Color (192, 255, 173);
00376   colormap_.col (190) = Color (191, 255, 172);
00377   colormap_.col (191) = Color (190, 255, 170);
00378   colormap_.col (192) = Color (189, 255, 169);
00379   colormap_.col (193) = Color (188, 255, 167);
00380   colormap_.col (194) = Color (186, 255, 166);
00381   colormap_.col (195) = Color (185, 255, 164);
00382   colormap_.col (196) = Color (184, 255, 163);
00383   colormap_.col (197) = Color (183, 255, 161);
00384   colormap_.col (198) = Color (181, 255, 160);
00385   colormap_.col (199) = Color (180, 255, 158);
00386   colormap_.col (200) = Color (179, 255, 157);
00387   colormap_.col (201) = Color (177, 255, 155);
00388   colormap_.col (202) = Color (176, 255, 154);
00389   colormap_.col (203) = Color (175, 255, 152);
00390   colormap_.col (204) = Color (173, 255, 150);
00391   colormap_.col (205) = Color (172, 255, 149);
00392   colormap_.col (206) = Color (170, 255, 147);
00393   colormap_.col (207) = Color (169, 255, 145);
00394   colormap_.col (208) = Color (166, 253, 143);
00395   colormap_.col (209) = Color (164, 252, 141);
00396   colormap_.col (210) = Color (162, 251, 138);
00397   colormap_.col (211) = Color (159, 250, 136);
00398   colormap_.col (212) = Color (157, 248, 134);
00399   colormap_.col (213) = Color (155, 247, 131);
00400   colormap_.col (214) = Color (152, 246, 129);
00401   colormap_.col (215) = Color (150, 245, 127);
00402   colormap_.col (216) = Color (148, 243, 124);
00403   colormap_.col (217) = Color (145, 242, 122);
00404   colormap_.col (218) = Color (143, 240, 119);
00405   colormap_.col (219) = Color (140, 239, 117);
00406   colormap_.col (220) = Color (138, 238, 114);
00407   colormap_.col (221) = Color (135, 236, 112);
00408   colormap_.col (222) = Color (133, 235, 110);
00409   colormap_.col (223) = Color (130, 233, 107);
00410   colormap_.col (224) = Color (128, 232, 105);
00411   colormap_.col (225) = Color (125, 230, 102);
00412   colormap_.col (226) = Color (122, 229, 100);
00413   colormap_.col (227) = Color (120, 227,  97);
00414   colormap_.col (228) = Color (117, 226,  94);
00415   colormap_.col (229) = Color (114, 224,  92);
00416   colormap_.col (230) = Color (111, 223,  89);
00417   colormap_.col (231) = Color (109, 221,  87);
00418   colormap_.col (232) = Color (106, 220,  84);
00419   colormap_.col (233) = Color (103, 218,  82);
00420   colormap_.col (234) = Color (100, 217,  79);
00421   colormap_.col (235) = Color ( 97, 215,  76);
00422   colormap_.col (236) = Color ( 94, 213,  73);
00423   colormap_.col (237) = Color ( 91, 212,  71);
00424   colormap_.col (238) = Color ( 88, 210,  68);
00425   colormap_.col (239) = Color ( 85, 208,  65);
00426   colormap_.col (240) = Color ( 82, 207,  62);
00427   colormap_.col (241) = Color ( 78, 205,  59);
00428   colormap_.col (242) = Color ( 75, 203,  57);
00429   colormap_.col (243) = Color ( 71, 201,  54);
00430   colormap_.col (244) = Color ( 68, 200,  50);
00431   colormap_.col (245) = Color ( 64, 198,  47);
00432   colormap_.col (246) = Color ( 60, 196,  44);
00433   colormap_.col (247) = Color ( 56, 195,  41);
00434   colormap_.col (248) = Color ( 52, 193,  37);
00435   colormap_.col (249) = Color ( 47, 191,  33);
00436   colormap_.col (250) = Color ( 42, 189,  29);
00437   colormap_.col (251) = Color ( 37, 187,  25);
00438   colormap_.col (252) = Color ( 31, 186,  20);
00439   colormap_.col (253) = Color ( 24, 184,  15);
00440   colormap_.col (254) = Color ( 14, 182,   7);
00441   colormap_.col (255) = Color (  0, 180,   0);
00442 }
00443 
00445 
00446 pcl::ihs::OpenGLViewer::~OpenGLViewer ()
00447 {
00448   this->stopTimer ();
00449 }
00450 
00452 
00453 bool
00454 pcl::ihs::OpenGLViewer::addMesh (const MeshConstPtr& mesh, const std::string& id, const Eigen::Isometry3d& T)
00455 {
00456   if (!mesh)
00457   {
00458     std::cerr << "ERROR in opengl_viewer.cpp: Input mesh is not valid.\n";
00459     return (false);
00460   }
00461 
00462   boost::mutex::scoped_lock lock (mutex_vis_);
00463 
00464   if (this->getMeshIsAdded (id))
00465     drawn_meshes_ [id] = FaceVertexMeshPtr (new FaceVertexMesh (*mesh, T));
00466   else
00467     drawn_meshes_.insert (std::make_pair (id, FaceVertexMeshPtr (new FaceVertexMesh (*mesh, T))));
00468 
00469   return (true);
00470 }
00471 
00473 
00474 bool
00475 pcl::ihs::OpenGLViewer::addMesh (const CloudXYZRGBNormalConstPtr& cloud, const std::string& id, const Eigen::Isometry3d& T)
00476 {
00477   if (!cloud)
00478   {
00479     std::cerr << "ERROR in opengl_viewer.cpp: Input cloud is not valid.\n";
00480     return (false);
00481   }
00482   if (!cloud->isOrganized ())
00483   {
00484     std::cerr << "ERROR in opengl_viewer.cpp: Input cloud is not organized.\n";
00485     return (false);
00486   }
00487 
00488   
00489   
00490   
00491   
00492   const int w        = cloud->width;
00493   const int h        = cloud->height;
00494   const int offset_1 = -w;
00495   const int offset_2 = -w - 1;
00496   const int offset_3 =    - 1;
00497 
00498   FaceVertexMeshPtr mesh (new FaceVertexMesh ());
00499   mesh->transformation = T;
00500 
00501   std::vector <int> indices (w * h, -1); 
00502   CloudIHS& vertices = mesh->vertices;
00503   std::vector <FaceVertexMesh::Triangle>& triangles = mesh->triangles;
00504   vertices.reserve (cloud->size ());
00505   triangles.reserve (2 * (w-1) * (h-1));
00506 
00507   
00508   struct AddVertex
00509   {
00510     inline int operator () (const PointXYZRGBNormal& pt, CloudIHS& vertices, int& ind_o) const
00511     {
00512       if (ind_o == -1)
00513       {
00514         ind_o = vertices.size ();
00515         vertices.push_back (PointIHS (pt, -pt.normal_z));
00516         std::swap (vertices.back ().r, vertices.back ().b);
00517       }
00518       return (ind_o);
00519     }
00520   };
00521   AddVertex addVertex;
00522 
00523   int ind_o_0, ind_o_1, ind_o_2, ind_o_3; 
00524   int ind_v_0, ind_v_1, ind_v_2, ind_v_3; 
00525 
00526   for (int r=1; r<h; ++r)
00527   {
00528     for (int c=1; c<w; ++c)
00529     {
00530       ind_o_0 = r*w + c;
00531       ind_o_1 = ind_o_0 + offset_1;
00532       ind_o_2 = ind_o_0 + offset_2;
00533       ind_o_3 = ind_o_0 + offset_3;
00534 
00535       const PointXYZRGBNormal& pt_0 = cloud->operator [] (ind_o_0);
00536       const PointXYZRGBNormal& pt_1 = cloud->operator [] (ind_o_1);
00537       const PointXYZRGBNormal& pt_2 = cloud->operator [] (ind_o_2);
00538       const PointXYZRGBNormal& pt_3 = cloud->operator [] (ind_o_3);
00539 
00540       if (!boost::math::isnan (pt_1.x) && !boost::math::isnan (pt_3.x))
00541       {
00542         if (!boost::math::isnan (pt_2.x)) 
00543         {
00544           if (std::abs (pt_1.z - pt_2.z) < 1 &&
00545               std::abs (pt_1.z - pt_3.z) < 1 &&
00546               std::abs (pt_2.z - pt_3.z) < 1) 
00547           {
00548             ind_v_1 = addVertex (pt_1, vertices, indices [ind_o_1]);
00549             ind_v_2 = addVertex (pt_2, vertices, indices [ind_o_2]);
00550             ind_v_3 = addVertex (pt_3, vertices, indices [ind_o_3]);
00551 
00552             triangles.push_back (FaceVertexMesh::Triangle (ind_v_1, ind_v_2, ind_v_3));
00553           }
00554         }
00555         if (!boost::math::isnan (pt_0.x)) 
00556         {
00557           if (std::abs (pt_0.z - pt_1.z) < 1 &&
00558               std::abs (pt_0.z - pt_3.z) < 1 &&
00559               std::abs (pt_1.z - pt_3.z) < 1) 
00560           {
00561             ind_v_1 = addVertex (pt_1, vertices, indices [ind_o_1]);
00562             ind_v_3 = addVertex (pt_3, vertices, indices [ind_o_3]);
00563             ind_v_0 = addVertex (pt_0, vertices, indices [ind_o_0]);
00564 
00565             triangles.push_back (FaceVertexMesh::Triangle (ind_v_1, ind_v_3, ind_v_0));
00566           }
00567         }
00568       }
00569     }
00570   }
00571 
00572   
00573   boost::mutex::scoped_lock lock (mutex_vis_);
00574 
00575   if (this->getMeshIsAdded (id))
00576     drawn_meshes_ [id] = mesh;
00577   else
00578     drawn_meshes_.insert (std::make_pair (id, mesh));
00579 
00580   return (true);
00581 }
00582 
00584 
00585 bool
00586 pcl::ihs::OpenGLViewer::removeMesh (const std::string& id)
00587 {
00588   boost::mutex::scoped_lock lock (mutex_vis_);
00589   if (!this->getMeshIsAdded (id)) return (false);
00590 
00591   drawn_meshes_.erase (id);
00592 
00593   return (true);
00594 }
00595 
00597 
00598 void
00599 pcl::ihs::OpenGLViewer::removeAllMeshes ()
00600 {
00601   boost::mutex::scoped_lock lock (mutex_vis_);
00602   drawn_meshes_.clear ();
00603 }
00604 
00606 
00607 void
00608 pcl::ihs::OpenGLViewer::setBoxCoefficients (const BoxCoefficients& coeffs)
00609 {
00610   boost::mutex::scoped_lock lock (mutex_vis_);
00611   box_coefficients_ = coeffs;
00612 }
00613 
00615 
00616 void
00617 pcl::ihs::OpenGLViewer::setDrawBox (const bool enabled)
00618 {
00619   boost::mutex::scoped_lock lock (mutex_vis_);
00620   draw_box_ = enabled;
00621 }
00622 
00624 
00625 bool
00626 pcl::ihs::OpenGLViewer::getDrawBox () const
00627 {
00628   return (draw_box_);
00629 }
00630 
00632 
00633 void
00634 pcl::ihs::OpenGLViewer::setPivot (const Eigen::Vector3d& pivot)
00635 {
00636   boost::mutex::scoped_lock lock (mutex_vis_);
00637   cam_pivot_ = pivot;
00638 }
00639 
00641 
00642 void
00643 pcl::ihs::OpenGLViewer::setPivot (const std::string& id)
00644 {
00645   boost::mutex::scoped_lock lock (mutex_vis_);
00646   cam_pivot_id_ = id;
00647 }
00648 
00650 
00651 void
00652 pcl::ihs::OpenGLViewer::stopTimer ()
00653 {
00654   boost::mutex::scoped_lock lock (mutex_vis_);
00655   if (timer_vis_)
00656   {
00657     timer_vis_->stop ();
00658   }
00659 }
00660 
00662 
00663 void
00664 pcl::ihs::OpenGLViewer::setVisibilityConfidenceNormalization (const float vis_conf_norm)
00665 {
00666   boost::mutex::scoped_lock lock (mutex_vis_);
00667 
00668   vis_conf_norm_ = vis_conf_norm < 1 ? 1 : vis_conf_norm;
00669 }
00670 
00672 
00673 QSize
00674 pcl::ihs::OpenGLViewer::minimumSizeHint () const
00675 {
00676   return (QSize (160, 120));
00677 }
00678 
00680 
00681 QSize
00682 pcl::ihs::OpenGLViewer::sizeHint () const
00683 {
00684   return (QSize (640, 480));
00685 }
00686 
00688 
00689 void
00690 pcl::ihs::OpenGLViewer::setScalingFactor (const double scale)
00691 {
00692   boost::mutex::scoped_lock lock (mutex_vis_);
00693   scaling_factor_ = scale;
00694 }
00695 
00697 
00698 void
00699 pcl::ihs::OpenGLViewer::timerCallback ()
00700 {
00701   QWidget::update ();
00702 }
00703 
00705 
00706 void
00707 pcl::ihs::OpenGLViewer::resetCamera ()
00708 {
00709   boost::mutex::scoped_lock lock (mutex_vis_);
00710 
00711   R_cam_ = Eigen::Quaterniond (1., 0., 0., 0.);
00712   t_cam_ = Eigen::Vector3d    (0., 0., 0.);
00713 }
00714 
00716 
00717 void
00718 pcl::ihs::OpenGLViewer::toggleMeshRepresentation ()
00719 {
00720   switch (mesh_representation_)
00721   {
00722     case MR_POINTS: this->setMeshRepresentation (MR_EDGES);  break;
00723     case MR_EDGES:  this->setMeshRepresentation (MR_FACES);  break;
00724     case MR_FACES:  this->setMeshRepresentation (MR_POINTS); break;
00725     default: std::cerr << "ERROR in opengl_viewer.cpp: Unknown mesh representation\n"; exit (EXIT_FAILURE);
00726   }
00727 }
00728 
00730 
00731 void
00732 pcl::ihs::OpenGLViewer::setMeshRepresentation (const MeshRepresentation& representation)
00733 {
00734   boost::mutex::scoped_lock lock (mutex_vis_);
00735 
00736   switch (mesh_representation_)
00737   {
00738     case MR_POINTS: std::cerr << "Drawing the points.\n";   break;
00739     case MR_EDGES:  std::cerr << "Drawing the edges.\n";  break;
00740     case MR_FACES:  std::cerr << "Drawing the faces.\n"; break;
00741     default: std::cerr << "ERROR in opengl_viewer.cpp: Unknown mesh representation\n"; exit (EXIT_FAILURE);
00742   }
00743 
00744   mesh_representation_ = representation;
00745 }
00746 
00748 
00749 void
00750 pcl::ihs::OpenGLViewer::toggleColoring ()
00751 {
00752   switch (coloring_)
00753   {
00754     case COL_RGB:       this->setColoring (COL_ONE_COLOR); break;
00755     case COL_ONE_COLOR: this->setColoring (COL_VISCONF);   break;
00756     case COL_VISCONF:   this->setColoring (COL_RGB);       break;
00757     default: std::cerr << "ERROR in opengl_viewer.cpp: Unknown coloring\n"; exit (EXIT_FAILURE);
00758   }
00759 }
00760 
00762 
00763 void
00764 pcl::ihs::OpenGLViewer::setColoring (const Coloring& coloring)
00765 {
00766   boost::mutex::scoped_lock lock (mutex_vis_);
00767 
00768   switch (coloring)
00769   {
00770     case COL_RGB:       std::cerr << "Coloring according to the rgb values.\n";            break;
00771     case COL_ONE_COLOR: std::cerr << "Use one color for all points.\n";                    break;
00772     case COL_VISCONF:   std::cerr << "Coloring according to the visibility confidence.\n"; break;
00773     default: std::cerr << "ERROR in opengl_viewer.cpp: Unknown coloring\n"; exit (EXIT_FAILURE);
00774   }
00775   coloring_ = coloring;
00776 }
00777 
00779 
00780 void
00781 pcl::ihs::OpenGLViewer::paintEvent (QPaintEvent* )
00782 {
00783   this->calcPivot ();
00784   this->makeCurrent ();
00785 
00786   
00787   glClearColor (0.f, 0.f, 0.f, 0.f);
00788   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00789 
00790   this->setupViewport (this->width (), this->height ());
00791 
00792   
00793   
00794   glMatrixMode(GL_MODELVIEW);
00795   glLoadIdentity();
00796 
00797   
00798   glLightfv (GL_LIGHT0, GL_AMBIENT , Eigen::Vector4f (0.1f, 0.1f, 0.1f, 1.0f).eval ().data ());
00799   glLightfv (GL_LIGHT0, GL_DIFFUSE , Eigen::Vector4f (0.6f, 0.6f, 0.6f, 1.0f).eval ().data () );
00800   glLightfv (GL_LIGHT0, GL_SPECULAR, Eigen::Vector4f (0.2f, 0.2f, 0.2f, 1.0f).eval ().data ());
00801   glLightfv (GL_LIGHT0, GL_POSITION, Eigen::Vector4f (0.3f, 0.5f, 0.8f, 0.0f).normalized ().eval ().data ());
00802 
00803   
00804   glLightfv (GL_LIGHT1, GL_AMBIENT , Eigen::Vector4f ( 0.0f, 0.0f, 0.0f, 1.0f).eval ().data ());
00805   glLightfv (GL_LIGHT1, GL_DIFFUSE , Eigen::Vector4f ( 0.3f, 0.3f, 0.3f, 1.0f).eval ().data () );
00806   glLightfv (GL_LIGHT1, GL_SPECULAR, Eigen::Vector4f ( 0.1f, 0.1f, 0.1f, 1.0f).eval ().data ());
00807   glLightfv (GL_LIGHT1, GL_POSITION, Eigen::Vector4f (-0.3f, 0.5f, 0.8f, 0.0f).normalized ().eval ().data ());
00808 
00809   
00810   glColorMaterial (GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
00811   glMaterialfv    (GL_FRONT, GL_SPECULAR , Eigen::Vector4f (0.1f, 0.1f, 0.1f, 1.0f).eval ().data ());
00812   glMaterialf     (GL_FRONT, GL_SHININESS, 25.f);
00813 
00814   glEnable (GL_DEPTH_TEST);
00815   glEnable (GL_NORMALIZE);
00816   glEnable (GL_COLOR_MATERIAL);
00817   glEnable (GL_LIGHTING);
00818   glEnable (GL_LIGHT0);
00819   glEnable (GL_LIGHT1);
00820 
00821   
00822   glMatrixMode   (GL_PROJECTION);
00823   glLoadIdentity ();
00824   gluPerspective (43., 4./3., 0.01 / scaling_factor_, 10. / scaling_factor_);
00825   glMatrixMode   (GL_MODELVIEW);
00826 
00827   
00828   Eigen::Quaterniond R_cam;
00829   Eigen::Vector3d    t_cam;
00830   {
00831     boost::mutex::scoped_lock lock (mutex_vis_);
00832     R_cam = R_cam_;
00833     t_cam = t_cam_;
00834   }
00835 
00836   const Eigen::Vector3d o  = Eigen::Vector3d::Zero  ();
00837   const Eigen::Vector3d ey = Eigen::Vector3d::UnitY ();
00838   const Eigen::Vector3d ez = Eigen::Vector3d::UnitZ ();
00839 
00840   const Eigen::Vector3d eye    =  R_cam * o  + t_cam;
00841   const Eigen::Vector3d center =  R_cam * ez + t_cam;
00842   const Eigen::Vector3d up     = (R_cam * -ey).normalized ();
00843 
00844   glMatrixMode (GL_MODELVIEW);
00845   gluLookAt (eye.   x (), eye.   y (), eye.   z (),
00846              center.x (), center.y (), center.z (),
00847              up.    x (), up.    y (), up.    z ());
00848 
00849   
00850   this->drawMeshes ();
00851 
00852   glDisable (GL_LIGHTING); 
00853   this->drawBox ();
00854 }
00855 
00857 
00858 bool
00859 pcl::ihs::OpenGLViewer::getMeshIsAdded (const std::string& id)
00860 {
00861   
00862   return (drawn_meshes_.find (id) != drawn_meshes_.end ());
00863 }
00864 
00866 
00867 void
00868 pcl::ihs::OpenGLViewer::calcPivot ()
00869 {
00870   boost::mutex::scoped_lock lock (mutex_vis_);
00871   if (this->getMeshIsAdded (cam_pivot_id_))
00872   {
00873     Eigen::Vector4f pivot;
00874     const FaceVertexMeshConstPtr mesh = drawn_meshes_ [cam_pivot_id_];
00875 
00876     if (pcl::compute3DCentroid (mesh->vertices, pivot))
00877     {
00878       const Eigen::Vector3d p = mesh->transformation * pivot.head <3> ().cast <double> ();
00879       lock.unlock ();
00880       this->setPivot (p);
00881     }
00882   }
00883   cam_pivot_id_.clear ();
00884 }
00885 
00887 
00888 void
00889 pcl::ihs::OpenGLViewer::drawMeshes ()
00890 {
00891   boost::mutex::scoped_lock lock (mutex_vis_);
00892 
00893   glEnableClientState (GL_VERTEX_ARRAY);
00894   glEnableClientState (GL_NORMAL_ARRAY);
00895   switch (coloring_)
00896   {
00897     case COL_RGB:       glEnableClientState  (GL_COLOR_ARRAY); break;
00898     case COL_ONE_COLOR: glDisableClientState (GL_COLOR_ARRAY); break;
00899     case COL_VISCONF:   glEnableClientState  (GL_COLOR_ARRAY); break;
00900     default: std::cerr << "ERROR in opengl_viewer.cpp: Unknown coloring\n"; exit (EXIT_FAILURE);
00901   }
00902   switch (mesh_representation_)
00903   {
00904     case MR_POINTS:                                             break;
00905     case MR_EDGES:  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); break;
00906     case MR_FACES:  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); break;
00907     default: std::cerr << "ERROR in opengl_viewer.cpp: Unknown mesh representation\n"; exit (EXIT_FAILURE);
00908   }
00909 
00910   for (FaceVertexMeshMap::const_iterator it=drawn_meshes_.begin (); it!=drawn_meshes_.end (); ++it)
00911   {
00912     if (it->second && !it->second->vertices.empty ())
00913     {
00914       const FaceVertexMesh& mesh = *it->second;
00915 
00916       glVertexPointer (3, GL_FLOAT, sizeof (PointIHS), &(mesh.vertices [0].x       ));
00917       glNormalPointer (   GL_FLOAT, sizeof (PointIHS), &(mesh.vertices [0].normal_x));
00918 
00919       Colors colors (3, mesh.vertices.size ());
00920 
00921       switch (coloring_)
00922       {
00923         case COL_RGB:
00924         {
00925           glColorPointer (3, GL_UNSIGNED_BYTE, sizeof (PointIHS), &(mesh.vertices [0].b));
00926           break;
00927         }
00928         case COL_ONE_COLOR:
00929         {
00930           glColor3f (.7f, .7f, .7f);
00931           break;
00932         }
00933         case COL_VISCONF:
00934         {
00935           for (unsigned int i=0; i<mesh.vertices.size (); ++i)
00936           {
00937             const unsigned int n = pcl::ihs::countDirections (mesh.vertices [i].directions);
00938             const unsigned int index = static_cast <unsigned int> (
00939                                          static_cast <float> (colormap_.cols ()) *
00940                                          static_cast <float> (n) / vis_conf_norm_);
00941 
00942             colors.col (i) = colormap_.col (index < 256 ? index : 255);
00943           }
00944 
00945           glColorPointer (3, GL_UNSIGNED_BYTE, 0, colors.data ());
00946         }
00947       }
00948 
00949       glPushMatrix ();
00950       {
00951         glMultMatrixd (mesh.transformation.matrix ().data ());
00952 
00953         switch (mesh_representation_)
00954         {
00955           case MR_POINTS:
00956           {
00957             glDrawArrays (GL_POINTS, 0, mesh.vertices.size ());
00958             break;
00959           }
00960           case MR_EDGES: case MR_FACES:
00961           {
00962             glDrawElements (GL_TRIANGLES, 3*mesh.triangles.size (), GL_UNSIGNED_INT, &mesh.triangles [0]);
00963             break;
00964           }
00965         }
00966       }
00967       glPopMatrix ();
00968     }
00969   }
00970 
00971   glDisableClientState (GL_VERTEX_ARRAY);
00972   glDisableClientState (GL_NORMAL_ARRAY);
00973   glDisableClientState (GL_COLOR_ARRAY);
00974   glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
00975 }
00976 
00978 
00979 void
00980 pcl::ihs::OpenGLViewer::drawBox ()
00981 {
00982   BoxCoefficients coeffs;
00983   {
00984     boost::mutex::scoped_lock lock (mutex_vis_);
00985     if (draw_box_) coeffs = box_coefficients_;
00986     else           return;
00987   }
00988 
00989   glColor3f (1.f, 1.f, 1.f);
00990 
00991   glPushMatrix ();
00992   {
00993     glMultMatrixd (coeffs.transformation.matrix ().data ());
00994 
00995     
00996     glBegin(GL_LINE_STRIP);
00997     {
00998       glVertex3f (coeffs.x_min, coeffs.y_min, coeffs.z_min);
00999       glVertex3f (coeffs.x_max, coeffs.y_min, coeffs.z_min);
01000       glVertex3f (coeffs.x_max, coeffs.y_max, coeffs.z_min);
01001       glVertex3f (coeffs.x_min, coeffs.y_max, coeffs.z_min);
01002       glVertex3f (coeffs.x_min, coeffs.y_min, coeffs.z_min);
01003     }
01004     glEnd();
01005 
01006     
01007     glBegin (GL_LINE_STRIP);
01008     {
01009       glVertex3f (coeffs.x_min, coeffs.y_min, coeffs.z_max);
01010       glVertex3f (coeffs.x_max, coeffs.y_min, coeffs.z_max);
01011       glVertex3f (coeffs.x_max, coeffs.y_max, coeffs.z_max);
01012       glVertex3f (coeffs.x_min, coeffs.y_max, coeffs.z_max);
01013       glVertex3f (coeffs.x_min, coeffs.y_min, coeffs.z_max);
01014     }
01015     glEnd();
01016 
01017     
01018     glBegin (GL_LINES);
01019     {
01020       glVertex3f (coeffs.x_min, coeffs.y_min, coeffs.z_min);
01021       glVertex3f (coeffs.x_min, coeffs.y_min, coeffs.z_max);
01022 
01023       glVertex3f (coeffs.x_max, coeffs.y_min, coeffs.z_min);
01024       glVertex3f (coeffs.x_max, coeffs.y_min, coeffs.z_max);
01025 
01026       glVertex3f (coeffs.x_max, coeffs.y_max, coeffs.z_min);
01027       glVertex3f (coeffs.x_max, coeffs.y_max, coeffs.z_max);
01028 
01029       glVertex3f (coeffs.x_min, coeffs.y_max, coeffs.z_min);
01030       glVertex3f (coeffs.x_min, coeffs.y_max, coeffs.z_max);
01031     }
01032     glEnd();
01033   }
01034   glPopMatrix ();
01035 }
01036 
01038 
01039 void
01040 pcl::ihs::OpenGLViewer::initializeGL ()
01041 {
01042 }
01043 
01045 
01046 void
01047 pcl::ihs::OpenGLViewer::setupViewport (const int w, const int h)
01048 {
01049   const float aspect_ratio = 4./3.;
01050 
01051   
01052   
01053   
01054   
01055   
01056   
01057   
01058   
01059   const float w_scaled = h * aspect_ratio;
01060   const float h_scaled = w / aspect_ratio;
01061 
01062   if (w < w_scaled)
01063   {
01064     glViewport (0, static_cast <GLint> ((h - h_scaled) / 2.f), w, static_cast <GLsizei> (h_scaled));
01065   }
01066   else
01067   {
01068     glViewport (static_cast <GLint> ((w - w_scaled) / 2.f), 0, static_cast <GLsizei> (w_scaled), h);
01069   }
01070 }
01071 
01073 
01074 void
01075 pcl::ihs::OpenGLViewer::resizeGL (int w, int h)
01076 {
01077   this->setupViewport (w, h);
01078 }
01079 
01081 
01082 void
01083 pcl::ihs::OpenGLViewer::mousePressEvent (QMouseEvent* )
01084 {
01085   boost::mutex::scoped_lock lock (mutex_vis_);
01086   mouse_pressed_begin_ = true;
01087 }
01088 
01090 
01091 void
01092 pcl::ihs::OpenGLViewer::mouseMoveEvent (QMouseEvent* event)
01093 {
01094   boost::mutex::scoped_lock lock (mutex_vis_);
01095 
01096   if (mouse_pressed_begin_)
01097   {
01098     x_prev_ = event->pos ().x ();
01099     y_prev_ = event->pos ().y ();
01100     mouse_pressed_begin_ = false;
01101     return;
01102   }
01103   if (event->pos ().x () == x_prev_ && event->pos ().y () == y_prev_) return;
01104   if (this->width () == 0 || this->height () == 0)                    return;
01105 
01106   const double dx = static_cast <double> (event->pos ().x ()) - static_cast <double> (x_prev_);
01107   const double dy = static_cast <double> (event->pos ().y ()) - static_cast <double> (y_prev_);
01108   const double w  = static_cast <double> (this->width ());
01109   const double h  = static_cast <double> (this->height ());
01110   const double d  = std::sqrt (w*w + h*h);
01111 
01112   const Eigen::Vector3d o  = Eigen::Vector3d::Zero  ();
01113   const Eigen::Vector3d ex = Eigen::Vector3d::UnitX ();
01114   const Eigen::Vector3d ey = Eigen::Vector3d::UnitY ();
01115   const Eigen::Vector3d ez = Eigen::Vector3d::UnitZ ();
01116 
01117   
01118   const double scale = std::max ((cam_pivot_ - R_cam_ * o - t_cam_).norm (), .1 / scaling_factor_) / d;
01119 
01120   if (QApplication::mouseButtons () == Qt::LeftButton)
01121   {
01122     const double          rot_angle = -7. * std::atan (std::sqrt ((dx*dx + dy*dy)) / d);
01123     const Eigen::Vector3d rot_axis  = (R_cam_ * ex * dy - R_cam_ * ey * dx).normalized ();
01124 
01125     const Eigen::Quaterniond dR (Eigen::AngleAxisd (rot_angle, rot_axis));
01126     t_cam_ = dR * (t_cam_ - cam_pivot_) + cam_pivot_;
01127     R_cam_ = (dR * R_cam_).normalized ();
01128   }
01129   else if (QApplication::mouseButtons () == Qt::MiddleButton)
01130   {
01131     t_cam_ += 1.3 * scale * Eigen::Vector3d (R_cam_ * (ey * -dy + ex * -dx));
01132   }
01133   else if (QApplication::mouseButtons () == Qt::RightButton)
01134   {
01135     t_cam_ += 2.6 * scale * Eigen::Vector3d (R_cam_ * (ez * -dy));
01136   }
01137 
01138   x_prev_ = event->pos ().x ();
01139   y_prev_ = event->pos ().y ();
01140 }
01141 
01143 
01144 void
01145 pcl::ihs::OpenGLViewer::wheelEvent (QWheelEvent* event)
01146 {
01147   if (QApplication::mouseButtons () == Qt::NoButton)
01148   {
01149     boost::mutex::scoped_lock lock (mutex_vis_);
01150 
01151     
01152     const Eigen::Vector3d o     = Eigen::Vector3d::Zero  ();
01153     const Eigen::Vector3d ez    = Eigen::Vector3d::UnitZ ();
01154     const double          w     = static_cast <double> (this->width ());
01155     const double          h     = static_cast <double> (this->height ());
01156     const double          d     = std::sqrt (w*w + h*h);
01157     const double          scale = std::max ((cam_pivot_ - R_cam_ * o - t_cam_).norm (), .1 / scaling_factor_) / d;
01158 
01159     
01160     t_cam_ += scale * Eigen::Vector3d (R_cam_ * (ez * static_cast <double> (event->delta ())));
01161   }
01162 }
01163