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