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 selectionTransformTool.cpp
37 /// @details the implementation of class CloudTransformTool
38 /// @author Yue Li and Matthew Hielsberg
39
40 #include <pcl/apps/point_cloud_editor/selectionTransformTool.h>
41 #include <pcl/apps/point_cloud_editor/cloud.h>
42 #include <pcl/apps/point_cloud_editor/selection.h>
43 #include <pcl/apps/point_cloud_editor/transformCommand.h>
44 #include <pcl/apps/point_cloud_editor/commandQueue.h>
45 #include <pcl/apps/point_cloud_editor/common.h>
46
47 const float SelectionTransformTool::DEFAULT_TRANSLATE_FACTOR_ = 0.001;
48
SelectionTransformTool(ConstSelectionPtr selection_ptr,CloudPtr cloud_ptr,CommandQueuePtr command_queue_ptr)49 SelectionTransformTool::SelectionTransformTool (ConstSelectionPtr selection_ptr,
50 CloudPtr cloud_ptr,
51 CommandQueuePtr command_queue_ptr)
52 : selection_ptr_(std::move(selection_ptr)),
53 cloud_ptr_(std::move(cloud_ptr)),
54 command_queue_ptr_(std::move(command_queue_ptr)),
55 translate_factor_(DEFAULT_TRANSLATE_FACTOR_)
56 {
57 std::fill_n(center_xyz_, XYZ_SIZE, 0);
58 setIdentity(transform_matrix_);
59 }
60
61 void
start(int x,int y,BitMask modifiers,BitMask buttons)62 SelectionTransformTool::start (int x, int y, BitMask modifiers, BitMask buttons)
63 {
64 if ((!cloud_ptr_) || (!selection_ptr_) || selection_ptr_->empty())
65 return;
66 if (!(buttons & LEFT))
67 return;
68 modifiers_ = modifiers;
69 x_ = x;
70 y_ = y;
71 findSelectionCenter();
72 setIdentity(transform_matrix_);
73 trackball_.start(x, y);
74 }
75
76 void
update(int x,int y,BitMask,BitMask buttons)77 SelectionTransformTool::update (int x, int y, BitMask, BitMask buttons)
78 {
79 if (!cloud_ptr_)
80 return;
81 if (!(buttons & LEFT))
82 return;
83 int dx = (x - x_);
84 int dy = (y - y_);
85 if (dx == 0 && dy == 0)
86 return;
87 trackball_.update(x, y);
88
89 if (modifiers_ & CTRL)
90 {
91 // selection motion is not applied directly (waits for end)
92 // as such we can not update x and y immediately
93 float scale = 1.0f / cloud_ptr_->getScalingFactor();
94 cloud_ptr_->setSelectionTranslation ((float) dx * translate_factor_ * scale,
95 (float) -dy * translate_factor_ * scale,
96 0.0f);
97 return;
98 }
99 if (modifiers_ & ALT)
100 {
101 // selection motion is not applied directly (waits for end)
102 // as such we can not update x and y immediately
103 float scale = 1.0f / cloud_ptr_->getScalingFactor();
104 cloud_ptr_->setSelectionTranslation (0.0f,
105 0.0f,
106 (float) dy * translate_factor_ * scale);
107 return;
108 }
109 float transform[MATRIX_SIZE];
110 trackball_.getRotationMatrix(transform);
111 transform_matrix_[12] -= center_xyz_[0];
112 transform_matrix_[13] -= center_xyz_[1];
113 transform_matrix_[14] -= center_xyz_[2];
114 ::multMatrix(transform_matrix_, transform, transform_matrix_);
115 transform_matrix_[12] += center_xyz_[0];
116 transform_matrix_[13] += center_xyz_[1];
117 transform_matrix_[14] += center_xyz_[2];
118 cloud_ptr_ -> setSelectionRotation(transform_matrix_);
119
120 x_ = x;
121 y_ = y;
122 }
123
124 void
end(int x,int y,BitMask modifiers,BitMask buttons)125 SelectionTransformTool::end (int x, int y, BitMask modifiers, BitMask buttons)
126 {
127 if (!(buttons & LEFT))
128 return;
129
130 float scale = 1.0f / cloud_ptr_->getScalingFactor();
131 int dx = (x - x_);
132 int dy = (y - y_);
133 update(x, y, modifiers, buttons);
134 if (modifiers_ & CTRL)
135 {
136 std::shared_ptr<TransformCommand> c(new TransformCommand(selection_ptr_,
137 cloud_ptr_, transform_matrix_, (float) dx * translate_factor_ * scale,
138 (float) -dy * translate_factor_ * scale, 0.0f));
139 command_queue_ptr_->execute(c);
140 }
141 else if (modifiers_ & ALT)
142 {
143 std::shared_ptr<TransformCommand> c(new TransformCommand(selection_ptr_,
144 cloud_ptr_, transform_matrix_, 0.0f, 0.0f,
145 (float) dy * translate_factor_ * scale));
146 command_queue_ptr_->execute(c);
147 }
148 else
149 {
150 std::shared_ptr<TransformCommand> c(new TransformCommand(selection_ptr_,
151 cloud_ptr_, transform_matrix_, 0.0f, 0.0f, 0.0f));
152 command_queue_ptr_->execute(c);
153 }
154 setIdentity(transform_matrix_);
155 cloud_ptr_->setSelectionRotation(transform_matrix_);
156 cloud_ptr_->setSelectionTranslation(0.0f, 0.0f, 0.0f);
157 }
158
159 /*void
160 SelectionTransformTool::getRotateMatrix (int dx, int dy,
161 float* rotation_matrix_a,
162 float* rotation_matrix_b,
163 BitMask buttons) const
164 {
165 setIdentity(rotation_matrix_a);
166 setIdentity(rotation_matrix_b);
167 float rad_dx = (float) dx * M_PI / 180.0f;
168 float rad_dy = (float) dy * M_PI / 180.0f;
169 rotation_matrix_a[5] = std::cos(rad_dy);
170 rotation_matrix_a[6] = std::sin(rad_dy);
171 rotation_matrix_a[9] = -std::sin(rad_dy);
172 rotation_matrix_a[10] = std::cos(rad_dy);
173 if (buttons & LEFT)
174 {
175 rotation_matrix_b[0] = std::cos(rad_dx);
176 rotation_matrix_b[2] = -std::sin(rad_dx);
177 rotation_matrix_b[8] = std::sin(rad_dx);
178 rotation_matrix_b[10] = std::cos(rad_dx);
179 }
180 else if (buttons & RIGHT)
181 {
182 rotation_matrix_b[0] = std::cos(rad_dx);
183 rotation_matrix_b[1] = std::sin(rad_dx);
184 rotation_matrix_b[4] = -std::sin(rad_dx);
185 rotation_matrix_b[5] = std::cos(rad_dx);
186 }
187 }*/
188
189 void
findSelectionCenter()190 SelectionTransformTool::findSelectionCenter ()
191 {
192 if (!selection_ptr_ || selection_ptr_->empty())
193 return;
194 float min_xyz[XYZ_SIZE] = {0.0f};
195 float max_xyz[XYZ_SIZE] = {0.0f};
196 Selection::const_iterator it = selection_ptr_->begin();
197 Point3D point_3d = cloud_ptr_->getObjectSpacePoint (*it);
198 float *pt = &(point_3d.data[X]);
199 std::copy(pt, pt+XYZ_SIZE, max_xyz);
200 std::copy(max_xyz, max_xyz+XYZ_SIZE, min_xyz);
201
202 for (++it; it != selection_ptr_->end(); ++it)
203 {
204 Point3D point_3d = cloud_ptr_->getObjectSpacePoint (*it);
205 pt = &(point_3d.data[X]);
206 for (unsigned int j = 0; j < XYZ_SIZE; ++j)
207 {
208 min_xyz[j] = std::min(min_xyz[j], pt[j]);
209 max_xyz[j] = std::max(max_xyz[j], pt[j]);
210 }
211 }
212 for (unsigned int j = 0; j < XYZ_SIZE; ++j)
213 {
214 center_xyz_[j] = 0.5f * (max_xyz[j] + min_xyz[j]);
215 }
216 }
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232