1 ///
2 /// Copyright (c) 2012, Texas A&M University
3 /// All rights reserved.
4 ///
5 /// Redistribution and use in source and binary forms, with or without
6 /// modification, are permitted provided that the following conditions
7 /// are met:
8 ///
9 ///  * Redistributions of source code must retain the above copyright
10 ///    notice, this list of conditions and the following disclaimer.
11 ///  * Redistributions in binary form must reproduce the above
12 ///    copyright notice, this list of conditions and the following
13 ///    disclaimer in the documentation and/or other materials provided
14 ///    with the distribution.
15 ///  * Neither the name of Texas A&M University nor the names of its
16 ///    contributors may be used to endorse or promote products derived
17 ///    from this software without specific prior written permission.
18 ///
19 /// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 /// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 /// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 /// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 /// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24 /// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 /// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 /// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 /// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 /// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 /// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 /// POSSIBILITY OF SUCH DAMAGE.
31 ///
32 /// The following software was written as part of a collaboration with the
33 /// University of South Carolina, Interdisciplinary Mathematics Institute.
34 ///
35 
36 /// @file   select1DTool.cpp
37 /// @details the implementation of Select1DTool class.
38 /// @author  Yue Li and Matthew Hielsberg
39 
40 #include <algorithm>
41 #include <qgl.h>
42 #include <pcl/apps/point_cloud_editor/select1DTool.h>
43 #include <pcl/apps/point_cloud_editor/cloud.h>
44 #include <pcl/apps/point_cloud_editor/selection.h>
45 #include <pcl/apps/point_cloud_editor/localTypes.h>
46 
Select1DTool(SelectionPtr selection_ptr,CloudPtr cloud_ptr)47 Select1DTool::Select1DTool (SelectionPtr selection_ptr, CloudPtr cloud_ptr)
48   : selection_ptr_(std::move(selection_ptr)), cloud_ptr_(std::move(cloud_ptr))
49 {
50 }
51 
52 void
end(int x,int y,BitMask modifiers,BitMask buttons)53 Select1DTool::end (int x, int y, BitMask modifiers, BitMask buttons)
54 {
55   if (!cloud_ptr_)
56     return;
57   if (!(buttons & LEFT))
58     return;
59 
60   unsigned int index = 0;
61   union
62   {
63     unsigned char pixel[4];// XXX - assume uchar = 1 byte
64     unsigned int id;
65   } u;
66   // XXX - The following assumes sizeof(unsigned int) == 4 bytes
67   glPushAttrib(GL_COLOR_BUFFER_BIT | GL_PIXEL_MODE_BIT | GL_HINT_BIT |
68                GL_LINE_BIT | GL_POINT_BIT);
69   {
70     glDisable(GL_POINT_SMOOTH);
71     glDisable(GL_LINE_SMOOTH);
72     glDisable( GL_BLEND );
73     glClearColor(0,0,0,0);
74     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
75     GLint viewport[4];
76     glGetIntegerv(GL_VIEWPORT, viewport);
77     IncIndex inc(1);// start the indexing from 1, since the clear color is 0
78     unsigned int *index_arr = new unsigned int[cloud_ptr_->size()];
79     std::generate_n(index_arr, cloud_ptr_->size(), inc);
80 
81     glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
82     {
83       glEnableClientState(GL_COLOR_ARRAY);
84       glColorPointer(4, GL_UNSIGNED_BYTE, 0, index_arr);
85       cloud_ptr_->draw(true);
86       glReadPixels(x, viewport[3] - y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, u.pixel);
87     }
88     glPopClientAttrib();
89     delete [] index_arr;
90   }
91   glPopAttrib();
92 
93   if (!u.id)
94     return; // no selection - they did not hit a point
95 
96   // the color buffer used [1,n] to color the points - retrieve the point index
97   index = u.id-1;
98 
99   if (modifiers & SHFT)
100   {
101     selection_ptr_->addIndex(index);
102   }
103   else if (modifiers & CTRL)
104   {
105     selection_ptr_->removeIndex(index);
106   }
107   else
108   {
109     selection_ptr_->clear();
110     selection_ptr_->addIndex(index);
111   }
112   cloud_ptr_->setSelection(selection_ptr_);
113 }
114