opengl_viewer.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  * Point Cloud Library (PCL) - www.pointclouds.org
00005  * Copyright (c) 2009-2012, Willow Garage, Inc.
00006  * Copyright (c) 2012-, Open Perception, Inc.
00007  *
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  *
00014  *  * Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  *  * Redistributions in binary form must reproduce the above
00017  *    copyright notice, this list of conditions and the following
00018  *    disclaimer in the documentation and/or other materials provided
00019  *    with the distribution.
00020  *  * Neither the name of the copyright holder(s) nor the names of its
00021  *    contributors may be used to endorse or promote products derived
00022  *    from this software without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00027  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00028  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00029  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00030  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00031  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00034  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00035  * POSSIBILITY OF SUCH DAMAGE.
00036  *
00037  * $Id$
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> // TODO: PointIHS is not registered
00060 #include <pcl/apps/in_hand_scanner/visibility_confidence.h>
00061 
00063 // FaceVertexMesh
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 // OpenGLViewer
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   // Timer: Defines the update rate for the visualization
00130   connect (timer_vis_.get (), SIGNAL (timeout ()), this, SLOT (timerCallback ()));
00131   timer_vis_->start (33);
00132 
00133   // http://doc.qt.digia.com/qt/opengl-overpainting.html
00134   QWidget::setAutoFillBackground (false);
00135 
00136   // http://doc.qt.digia.com/qt/qwidget.html#keyPressEvent
00137   this->setFocusPolicy (Qt::StrongFocus);
00138 
00139   // http://doc.qt.digia.com/qt/qmetatype.html#qRegisterMetaType
00140   qRegisterMetaType <pcl::ihs::OpenGLViewer::MeshRepresentation> ("MeshRepresentation");
00141   qRegisterMetaType <pcl::ihs::OpenGLViewer::Coloring>           ("Coloring");
00142 
00144   // Code to generate the colormap (I don't want to link against vtk just for the colormap).
00146 
00147   //#include <cstdlib>
00148   //#include <iomanip>
00149 
00150   //#include <vtkColorTransferFunction.h>
00151   //#include <vtkSmartPointer.h>
00152 
00153   //int
00154   //main ()
00155   //{
00156   //  static const unsigned int n = 256;
00157   //  // double rgb_1 [] = { 59./255., 76./255., 192./255.};
00158   //  // double rgb_2 [] = {180./255.,  4./255.,  38./255.};
00159   //  double rgb_1 [] = {180./255.,   0./255.,  0./255.};
00160   //  double rgb_2 [] = {  0./255., 180./255.,  0./255.};
00161 
00162   //  vtkSmartPointer <vtkColorTransferFunction> ctf = vtkColorTransferFunction::New ();
00163   //  ctf->SetColorSpaceToDiverging ();
00164   //  ctf->AddRGBPoint (  0., rgb_1 [0], rgb_1 [1], rgb_1 [2]);
00165   //  ctf->AddRGBPoint (  1., rgb_2 [0], rgb_2 [1], rgb_2 [2]);
00166   //  ctf->Build ();
00167 
00168   //  const unsigned char* colormap = ctf->GetTable (0., 1., n);
00169 
00170   //  for (unsigned int i=0; i<n; ++i)
00171   //  {
00172   //    const unsigned int r = static_cast <unsigned int> (colormap [3 * i    ]);
00173   //    const unsigned int g = static_cast <unsigned int> (colormap [3 * i + 1]);
00174   //    const unsigned int b = static_cast <unsigned int> (colormap [3 * i + 2]);
00175 
00176   //    std::cerr << "colormap_.col ("
00177   //              << std::setw (3) << i << ") = Color ("
00178   //              << std::setw (3) << r << ", "
00179   //              << std::setw (3) << g << ", "
00180   //              << std::setw (3) << b << ");\n";
00181   //  }
00182 
00183   //  return (EXIT_SUCCESS);
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   // Convert the cloud to a mesh using the following pattern
00489   // 2 - 1 //
00490   // | / | //
00491   // 3 - 0 //
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); // Map the original indices to the vertex indices.
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   // Helper functor
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; // Index into the organized cloud.
00524   int ind_v_0, ind_v_1, ind_v_2, ind_v_3; // Index to the new vertices.
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)) // 1-2-3 is valid
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) // distance threshold
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)) // 0-1-3 is valid
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) // distance threshold
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   // Finally add the mesh.
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* /*event*/)
00782 {
00783   this->calcPivot ();
00784   this->makeCurrent ();
00785 
00786   // Clear information from the last draw
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   // Move light with camera (see example 5-7)
00793   // http://www.glprogramming.com/red/chapter05.html
00794   glMatrixMode(GL_MODELVIEW);
00795   glLoadIdentity();
00796 
00797   // light 0 (directional)
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   // light 1 (directional)
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   // Material
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   // Projection matrix
00822   glMatrixMode   (GL_PROJECTION);
00823   glLoadIdentity ();
00824   gluPerspective (43., 4./3., 0.01 / scaling_factor_, 10. / scaling_factor_);
00825   glMatrixMode   (GL_MODELVIEW);
00826 
00827   // ModelView matrix
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   // Draw everything
00850   this->drawMeshes ();
00851 
00852   glDisable (GL_LIGHTING); // This is needed so the color is right.
00853   this->drawBox ();
00854 }
00855 
00857 
00858 bool
00859 pcl::ihs::OpenGLViewer::getMeshIsAdded (const std::string& id)
00860 {
00861   // boost::mutex::scoped_lock lock (mutex_vis_);
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     // Front
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     // Back
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     // Sides
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   // Use the biggest possible area of the window to draw to
01052   //    case 1 (w < w_scaled):        case 2 (w >= w_scaled):
01053   //      w
01054   //    |---|         ^               |-------------|  ^
01055   //    |---| ^       |               |    |   |    |  | h
01056   //    |   | | h_sc  | h             |-------------|  v
01057   //    |---| v       |                    <---> w_sc
01058   //    |---|         v               <----- w ----->
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* /*event*/)
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   // Scale with the distance between the pivot and camera eye.
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     // Scale with the distance between the pivot and camera eye.
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     // http://doc.qt.digia.com/qt/qwheelevent.html#delta
01160     t_cam_ += scale * Eigen::Vector3d (R_cam_ * (ez * static_cast <double> (event->delta ())));
01161   }
01162 }
01163 


ros_in_hand_scanner
Author(s):
autogenerated on Thu Jun 6 2019 20:39:38