selected_trackball_interactor_style.cpp
Go to the documentation of this file.
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     //Fetch the actor we manipulated
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     //Fetch the actor we manipulated
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   // First get the origin of the assembly
00118   double *obj_center = this->InteractionProp->GetCenter();
00119   
00120   // GetLength gets the length of the diagonal of the bounding box
00121   double boundRadius = this->InteractionProp->GetLength() * 0.5;
00122   
00123   // Get the view up and view right vectors
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   // Get the furtherest point from object position+origin
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   // Convert them to display coord
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   // Get the axis to rotate around = vector from eye to origin
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     // If parallel projection, want to get the view plane normal...
00230     cam->ComputeViewPlaneNormal();
00231     cam->GetViewPlaneNormal( motion_vector );
00232   }
00233   else
00234   {   
00235     // Perspective projection, get vector from eye to center of actor
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   // Use initial center as the origin from which to pan
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 }


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:33:22