00001 #include <pcl/apps/cloud_composer/point_selectors/selected_trackball_interactor_style.h>
00002 #include <pcl/apps/cloud_composer/project_model.h>
00003
00004 namespace pcl
00005 {
00006 namespace cloud_composer
00007 {
00008 vtkStandardNewMacro(SelectedTrackballStyleInteractor);
00009 }
00010 }
00011
00012 pcl::cloud_composer::SelectedTrackballStyleInteractor::SelectedTrackballStyleInteractor ()
00013 : vtkInteractorStyleTrackballActor ()
00014 {
00015 manipulation_complete_event_ = interactor_events::MANIPULATION_COMPLETE_EVENT;
00016
00017 }
00018
00019 pcl::cloud_composer::SelectedTrackballStyleInteractor::~SelectedTrackballStyleInteractor ()
00020 {
00021
00022 }
00023
00024 void
00025 pcl::cloud_composer::SelectedTrackballStyleInteractor::setSelectedActors ()
00026 {
00027 QList <QString> selected_cloud_ids;
00028 QModelIndexList selected_indexes = model_->getSelectionModel()->selectedIndexes ();
00029 foreach (QModelIndex index, selected_indexes)
00030 {
00031 QStandardItem* item = model_->itemFromIndex (index);
00032 CloudItem* cloud_item = dynamic_cast <CloudItem*> (item);
00033 if (cloud_item)
00034 selected_cloud_ids.append (cloud_item->getId ());
00035 }
00036
00037 pcl::visualization::CloudActorMap::iterator it;
00038 for (it = actors_->begin (); it != actors_->end (); ++it)
00039 {
00040 QString id = QString::fromStdString (it->first);
00041 if (selected_cloud_ids.contains (id))
00042 {
00043 vtkLODActor* actor = (it->second).actor;
00044 qDebug () << "Adding "<<id<< " to selected manip! ptr ="<<actor;
00045 selected_actors_map_.insert (id ,actor);
00046 vtkSmartPointer<vtkMatrix4x4> start_matrix = vtkSmartPointer<vtkMatrix4x4>::New ();
00047 actor->GetMatrix (start_matrix);
00048 start_matrix_map_.insert (id,start_matrix);
00049 }
00050 }
00051 }
00052
00053 void
00054 pcl::cloud_composer::SelectedTrackballStyleInteractor::OnLeftButtonDown ()
00055 {
00056 vtkInteractorStyleTrackballActor::OnLeftButtonDown();
00057
00058 setSelectedActors ();
00059
00060 }
00061
00062 void
00063 pcl::cloud_composer::SelectedTrackballStyleInteractor::OnRightButtonDown ()
00064 {
00065 vtkInteractorStyleTrackballActor::OnRightButtonDown();
00066
00067 setSelectedActors ();
00068
00069 }
00070
00071 void
00072 pcl::cloud_composer::SelectedTrackballStyleInteractor::OnLeftButtonUp ()
00073 {
00074 vtkInteractorStyleTrackballActor::OnLeftButtonUp();
00075 foreach (QString id, selected_actors_map_.keys ())
00076 {
00077 vtkLODActor* actor = selected_actors_map_.value (id);
00078 ManipulationEvent* manip_event = new ManipulationEvent ();
00079
00080 vtkSmartPointer<vtkMatrix4x4> end_matrix = vtkSmartPointer<vtkMatrix4x4>::New ();
00081 actor->GetMatrix (end_matrix);
00082 manip_event->addManipulation (id, start_matrix_map_.value (id), end_matrix);
00083 this->InvokeEvent (this->manipulation_complete_event_, manip_event);
00084
00085 }
00086 }
00087
00088 void
00089 pcl::cloud_composer::SelectedTrackballStyleInteractor::OnRightButtonUp ()
00090 {
00091 vtkInteractorStyleTrackballActor::OnRightButtonUp();
00092 foreach (QString id, selected_actors_map_.keys ())
00093 {
00094 vtkLODActor* actor = selected_actors_map_.value (id);
00095 ManipulationEvent* manip_event = new ManipulationEvent ();
00096
00097 vtkSmartPointer<vtkMatrix4x4> end_matrix = vtkSmartPointer<vtkMatrix4x4>::New ();
00098 actor->GetMatrix (end_matrix);
00099 manip_event->addManipulation (id, start_matrix_map_.value (id), end_matrix);
00100 this->InvokeEvent (this->manipulation_complete_event_, manip_event);
00101
00102 }
00103 }
00104
00105 void
00106 pcl::cloud_composer::SelectedTrackballStyleInteractor::Rotate ()
00107 {
00108 if (this->CurrentRenderer == NULL || this->InteractionProp == NULL)
00109 {
00110 return;
00111 }
00112
00113 vtkRenderWindowInteractor *rwi = this->Interactor;
00114 vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
00115
00116
00117
00118 double *obj_center = this->InteractionProp->GetCenter();
00119
00120
00121 double boundRadius = this->InteractionProp->GetLength() * 0.5;
00122
00123
00124 double view_up[3], view_look[3], view_right[3];
00125
00126 cam->OrthogonalizeViewUp();
00127 cam->ComputeViewPlaneNormal();
00128 cam->GetViewUp(view_up);
00129 vtkMath::Normalize(view_up);
00130 cam->GetViewPlaneNormal(view_look);
00131 vtkMath::Cross(view_up, view_look, view_right);
00132 vtkMath::Normalize(view_right);
00133
00134
00135 double outsidept[3];
00136
00137 outsidept[0] = obj_center[0] + view_right[0] * boundRadius;
00138 outsidept[1] = obj_center[1] + view_right[1] * boundRadius;
00139 outsidept[2] = obj_center[2] + view_right[2] * boundRadius;
00140
00141
00142 double disp_obj_center[3];
00143
00144 this->ComputeWorldToDisplay(obj_center[0], obj_center[1], obj_center[2],
00145 disp_obj_center);
00146
00147 this->ComputeWorldToDisplay(outsidept[0], outsidept[1], outsidept[2],
00148 outsidept);
00149
00150 double radius = sqrt(vtkMath::Distance2BetweenPoints(disp_obj_center,
00151 outsidept));
00152 double nxf = (rwi->GetEventPosition()[0] - disp_obj_center[0]) / radius;
00153
00154 double nyf = (rwi->GetEventPosition()[1] - disp_obj_center[1]) / radius;
00155
00156 double oxf = (rwi->GetLastEventPosition()[0] - disp_obj_center[0]) / radius;
00157
00158 double oyf = (rwi->GetLastEventPosition()[1] - disp_obj_center[1]) / radius;
00159
00160 if (((nxf * nxf + nyf * nyf) <= 1.0) &&
00161 ((oxf * oxf + oyf * oyf) <= 1.0))
00162 {
00163 double newXAngle = vtkMath::DegreesFromRadians( asin( nxf ) );
00164 double newYAngle = vtkMath::DegreesFromRadians( asin( nyf ) );
00165 double oldXAngle = vtkMath::DegreesFromRadians( asin( oxf ) );
00166 double oldYAngle = vtkMath::DegreesFromRadians( asin( oyf ) );
00167
00168 double scale[3];
00169 scale[0] = scale[1] = scale[2] = 1.0;
00170
00171 double **rotate = new double*[2];
00172
00173 rotate[0] = new double[4];
00174 rotate[1] = new double[4];
00175
00176 rotate[0][0] = newXAngle - oldXAngle;
00177 rotate[0][1] = view_up[0];
00178 rotate[0][2] = view_up[1];
00179 rotate[0][3] = view_up[2];
00180
00181 rotate[1][0] = oldYAngle - newYAngle;
00182 rotate[1][1] = view_right[0];
00183 rotate[1][2] = view_right[1];
00184 rotate[1][3] = view_right[2];
00185
00186 foreach (QString id, selected_actors_map_.keys ())
00187 {
00188 vtkLODActor* actor = selected_actors_map_.value (id);
00189 this->Prop3DTransform(actor,
00190 obj_center,
00191 2,
00192 rotate,
00193 scale);
00194 }
00195 delete [] rotate[0];
00196 delete [] rotate[1];
00197 delete [] rotate;
00198 }
00199
00200 if (this->AutoAdjustCameraClippingRange)
00201 {
00202 this->CurrentRenderer->ResetCameraClippingRange();
00203 }
00204
00205 rwi->Render();
00206
00207 }
00208
00209 void
00210 pcl::cloud_composer::SelectedTrackballStyleInteractor::Spin ()
00211 {
00212 if ( this->CurrentRenderer == NULL || this->InteractionProp == NULL )
00213 {
00214 return;
00215 }
00216
00217 vtkRenderWindowInteractor *rwi = this->Interactor;
00218 vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
00219
00220
00221
00222 double *obj_center = this->InteractionProp->GetCenter();
00223
00224 double motion_vector[3];
00225 double view_point[3];
00226
00227 if (cam->GetParallelProjection())
00228 {
00229
00230 cam->ComputeViewPlaneNormal();
00231 cam->GetViewPlaneNormal( motion_vector );
00232 }
00233 else
00234 {
00235
00236 cam->GetPosition( view_point );
00237 motion_vector[0] = view_point[0] - obj_center[0];
00238 motion_vector[1] = view_point[1] - obj_center[1];
00239 motion_vector[2] = view_point[2] - obj_center[2];
00240 vtkMath::Normalize(motion_vector);
00241 }
00242
00243 double disp_obj_center[3];
00244
00245 this->ComputeWorldToDisplay(obj_center[0], obj_center[1], obj_center[2],
00246 disp_obj_center);
00247
00248 double newAngle =
00249 vtkMath::DegreesFromRadians( atan2( rwi->GetEventPosition()[1] - disp_obj_center[1],
00250 rwi->GetEventPosition()[0] - disp_obj_center[0] ) );
00251
00252 double oldAngle =
00253 vtkMath::DegreesFromRadians( atan2( rwi->GetLastEventPosition()[1] - disp_obj_center[1],
00254 rwi->GetLastEventPosition()[0] - disp_obj_center[0] ) );
00255
00256 double scale[3];
00257 scale[0] = scale[1] = scale[2] = 1.0;
00258
00259 double **rotate = new double*[1];
00260 rotate[0] = new double[4];
00261
00262 rotate[0][0] = newAngle - oldAngle;
00263 rotate[0][1] = motion_vector[0];
00264 rotate[0][2] = motion_vector[1];
00265 rotate[0][3] = motion_vector[2];
00266
00267 foreach (QString id, selected_actors_map_.keys ())
00268 {
00269 vtkLODActor* actor = selected_actors_map_.value (id);
00270 this->Prop3DTransform(actor,
00271 obj_center,
00272 1,
00273 rotate,
00274 scale);
00275 }
00276
00277 delete [] rotate[0];
00278 delete [] rotate;
00279
00280 if ( this->AutoAdjustCameraClippingRange )
00281 {
00282 this->CurrentRenderer->ResetCameraClippingRange();
00283 }
00284
00285 rwi->Render();
00286 }
00287
00288 void
00289 pcl::cloud_composer::SelectedTrackballStyleInteractor::Pan ()
00290 {
00291 if (this->CurrentRenderer == NULL || this->InteractionProp == NULL)
00292 {
00293 return;
00294 }
00295
00296 vtkRenderWindowInteractor *rwi = this->Interactor;
00297
00298
00299
00300 double *obj_center = this->InteractionProp->GetCenter();
00301
00302 double disp_obj_center[3], new_pick_point[4];
00303 double old_pick_point[4], motion_vector[3];
00304
00305 this->ComputeWorldToDisplay(obj_center[0], obj_center[1], obj_center[2],
00306 disp_obj_center);
00307
00308 this->ComputeDisplayToWorld(rwi->GetEventPosition()[0],
00309 rwi->GetEventPosition()[1],
00310 disp_obj_center[2],
00311 new_pick_point);
00312
00313 this->ComputeDisplayToWorld(rwi->GetLastEventPosition()[0],
00314 rwi->GetLastEventPosition()[1],
00315 disp_obj_center[2],
00316 old_pick_point);
00317
00318 motion_vector[0] = new_pick_point[0] - old_pick_point[0];
00319 motion_vector[1] = new_pick_point[1] - old_pick_point[1];
00320 motion_vector[2] = new_pick_point[2] - old_pick_point[2];
00321
00322 foreach (QString id, selected_actors_map_.keys ())
00323 {
00324 vtkLODActor* actor = selected_actors_map_.value (id);
00325 if (actor->GetUserMatrix() != NULL)
00326 {
00327 vtkTransform *t = vtkTransform::New();
00328 t->PostMultiply();
00329 t->SetMatrix(actor->GetUserMatrix());
00330 t->Translate(motion_vector[0], motion_vector[1], motion_vector[2]);
00331 actor->GetUserMatrix()->DeepCopy(t->GetMatrix());
00332 t->Delete();
00333 }
00334 else
00335 {
00336 actor->AddPosition(motion_vector[0],
00337 motion_vector[1],
00338 motion_vector[2]);
00339 }
00340 }
00341
00342
00343 if (this->AutoAdjustCameraClippingRange)
00344 {
00345 this->CurrentRenderer->ResetCameraClippingRange();
00346 }
00347
00348 rwi->Render();
00349 }
00350
00351 void
00352 pcl::cloud_composer::SelectedTrackballStyleInteractor::UniformScale ()
00353 {
00354 if (this->CurrentRenderer == NULL || this->InteractionProp == NULL)
00355 {
00356 return;
00357 }
00358
00359 vtkRenderWindowInteractor *rwi = this->Interactor;
00360
00361 int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
00362
00363 double *obj_center = this->InteractionProp->GetCenter();
00364 double *center = this->CurrentRenderer->GetCenter();
00365
00366 double yf = dy / center[1] * this->MotionFactor;
00367 double scaleFactor = pow(1.1, yf);
00368
00369 double **rotate = NULL;
00370
00371 double scale[3];
00372 scale[0] = scale[1] = scale[2] = scaleFactor;
00373 foreach (QString id, selected_actors_map_.keys ())
00374 {
00375 vtkLODActor* actor = selected_actors_map_.value (id);
00376 this->Prop3DTransform(actor,
00377 obj_center,
00378 0,
00379 rotate,
00380 scale);
00381 }
00382
00383 if (this->AutoAdjustCameraClippingRange)
00384 {
00385 this->CurrentRenderer->ResetCameraClippingRange();
00386 }
00387
00388 rwi->Render();
00389
00390 }