CloudViewerInteractorStyle.cpp
Go to the documentation of this file.
00001 /*
00002  * CloudViewerInteractorStyl.cpp
00003  *
00004  *  Created on: Aug 21, 2018
00005  *      Author: mathieu
00006  */
00007 
00008 #include "rtabmap/gui/CloudViewerInteractorStyle.h"
00009 #include "rtabmap/gui/CloudViewer.h"
00010 #include "rtabmap/gui/CloudViewerCellPicker.h"
00011 
00012 #include "rtabmap/utilite/ULogger.h"
00013 #include "rtabmap/utilite/UConversion.h"
00014 #include "rtabmap/utilite/UMath.h"
00015 
00016 #include <vtkRenderer.h>
00017 #include <vtkRenderWindow.h>
00018 #include <vtkObjectFactory.h>
00019 #include <vtkOBBTree.h>
00020 #include <vtkCamera.h>
00021 
00022 namespace rtabmap {
00023 
00024 // Standard VTK macro for *New ()
00025 vtkStandardNewMacro (CloudViewerInteractorStyle);
00026 
00027 CloudViewerInteractorStyle::CloudViewerInteractorStyle() :
00028         pcl::visualization::PCLVisualizerInteractorStyle(),
00029         viewer_(0),
00030         NumberOfClicks(0),
00031         ResetPixelDistance(0),
00032         pointsHolder_(new pcl::PointCloud<pcl::PointXYZRGB>),
00033         orthoMode_(false)
00034 {
00035         PreviousPosition[0] = PreviousPosition[1] = 0;
00036         PreviousMeasure[0] = PreviousMeasure[1] =  PreviousMeasure[2] = 0.0f;
00037 
00038         this->MotionFactor = 5;
00039 }
00040 
00041 void CloudViewerInteractorStyle::Rotate()
00042 {
00043         if (this->CurrentRenderer == NULL)
00044         {
00045                 return;
00046         }
00047 
00048         vtkRenderWindowInteractor *rwi = this->Interactor;
00049 
00050         int dx = rwi->GetEventPosition()[0] - rwi->GetLastEventPosition()[0];
00051         int dy = orthoMode_?0:rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
00052 
00053         int *size = this->CurrentRenderer->GetRenderWindow()->GetSize();
00054 
00055         double delta_elevation = -20.0 / size[1];
00056         double delta_azimuth = -20.0 / size[0];
00057 
00058         double rxf = dx * delta_azimuth * this->MotionFactor;
00059         double ryf = dy * delta_elevation * this->MotionFactor;
00060 
00061         vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
00062         UASSERT(camera);
00063         if(!orthoMode_)
00064         {
00065                 camera->Azimuth(rxf);
00066                 camera->Elevation(ryf);
00067                 camera->OrthogonalizeViewUp();
00068         }
00069         else
00070         {
00071                 camera->Roll(-rxf);
00072         }
00073 
00074         if (this->AutoAdjustCameraClippingRange)
00075         {
00076                 this->CurrentRenderer->ResetCameraClippingRange();
00077         }
00078 
00079         if (rwi->GetLightFollowCamera())
00080         {
00081                 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
00082         }
00083 
00084         //rwi->Render();
00085 }
00086 
00087 void CloudViewerInteractorStyle::setOrthoMode(bool enabled)
00088 {
00089         if (this->CurrentRenderer == NULL)
00090         {
00091                 return;
00092         }
00093 
00094         vtkCamera *camera = CurrentRenderer->GetActiveCamera ();
00095         UASSERT(camera);
00096         camera->SetParallelProjection (enabled);
00097         if(enabled)
00098         {
00099                 double x,y,z;
00100                 camera->GetFocalPoint(x, y, z);
00101                 camera->SetPosition(x, y, z+(camera->GetDistance()<=5?5:camera->GetDistance()));
00102                 camera->SetViewUp(1, 0, 0);
00103         }
00104         CurrentRenderer->SetActiveCamera (camera);
00105         orthoMode_ = enabled;
00106 }
00107 
00108 void CloudViewerInteractorStyle::OnMouseMove()
00109 {
00110         if(this->CurrentRenderer &&
00111                 this->CurrentRenderer->GetLayer() == 1 &&
00112                 this->GetInteractor()->GetShiftKey() && this->GetInteractor()->GetControlKey() &&
00113                 viewer_ &&
00114                 viewer_->getLocators().size())
00115         {
00116                 CloudViewerCellPicker * cellPicker = dynamic_cast<CloudViewerCellPicker*>(this->Interactor->GetPicker());
00117                 if(cellPicker)
00118                 {
00119                         int pickPosition[2];
00120                         this->GetInteractor()->GetEventPosition(pickPosition);
00121                         this->Interactor->GetPicker()->Pick(pickPosition[0], pickPosition[1],
00122                                         0,  // always zero.
00123                                         this->CurrentRenderer);
00124                         double picked[3];
00125                         this->Interactor->GetPicker()->GetPickPosition(picked);
00126 
00127                         UDEBUG("Control move! Picked value: %f %f %f", picked[0], picked[1], picked[2]);
00128 
00129                         float textSize = 0.05;
00130 
00131                         viewer_->removeCloud("interactor_points_alt");
00132                         pointsHolder_->resize(2);
00133                         pcl::PointXYZRGB pt(255,0,0);
00134                         pt.x = picked[0];
00135                         pt.y = picked[1];
00136                         pt.z = picked[2];
00137                         pointsHolder_->at(0) = pt;
00138 
00139                         viewer_->removeLine("interactor_ray_alt");
00140                         viewer_->removeText("interactor_ray_text_alt");
00141 
00142                         // Intersect the locator with the line
00143                         double length = 5.0;
00144                         double pickedNormal[3];
00145                         cellPicker->GetPickNormal(pickedNormal);
00146                         double lineP0[3] = {picked[0], picked[1], picked[2]};
00147                         double lineP1[3] = {picked[0]+pickedNormal[0]*length, picked[1]+pickedNormal[1]*length, picked[2]+pickedNormal[2]*length};
00148                         vtkSmartPointer<vtkPoints> intersectPoints = vtkSmartPointer<vtkPoints>::New();
00149 
00150                         viewer_->getLocators().begin()->second->IntersectWithLine(lineP0, lineP1, intersectPoints, NULL);
00151 
00152                         // Display list of intersections
00153                         double intersection[3];
00154                         double previous[3] = {picked[0], picked[1], picked[2]};
00155                         for(int i = 0; i < intersectPoints->GetNumberOfPoints(); i++ )
00156                         {
00157                                 intersectPoints->GetPoint(i, intersection);
00158 
00159                                 Eigen::Vector3f v(intersection[0]-previous[0], intersection[1]-previous[1], intersection[2]-previous[2]);
00160                                 float n = v.norm();
00161                                 if(n  > 0.01f)
00162                                 {
00163                                         v/=n;
00164                                         v *= n/2.0f;
00165                                         pt.r = 125;
00166                                         pt.g = 125;
00167                                         pt.b = 125;
00168                                         pt.x = intersection[0];
00169                                         pt.y = intersection[1];
00170                                         pt.z = intersection[2];
00171                                         pointsHolder_->at(1) = pt;
00172                                         viewer_->addOrUpdateText("interactor_ray_text_alt", uFormat("%.2f m", n),
00173                                                         Transform(previous[0]+v[0], previous[1]+v[1],previous[2]+v[2], 0, 0, 0),
00174                                                         textSize,
00175                                                         Qt::gray);
00176                                         viewer_->addOrUpdateLine("interactor_ray_alt",
00177                                                         Transform(previous[0], previous[1], previous[2], 0, 0, 0),
00178                                                         Transform(intersection[0], intersection[1], intersection[2], 0, 0, 0),
00179                                                         Qt::gray);
00180 
00181                                         previous[0] = intersection[0];
00182                                         previous[1] = intersection[1];
00183                                         previous[2] = intersection[2];
00184                                         break;
00185                                 }
00186                         }
00187                         viewer_->addCloud("interactor_points_alt", pointsHolder_);
00188                         viewer_->setCloudPointSize("interactor_points_alt", 15);
00189                         viewer_->setCloudOpacity("interactor_points_alt", 0.5);
00190                 }
00191         }
00192         // Forward events
00193         PCLVisualizerInteractorStyle::OnMouseMove();
00194 }
00195 
00196 void CloudViewerInteractorStyle::OnLeftButtonDown()
00197 {
00198         // http://www.vtk.org/Wiki/VTK/Examples/Cxx/Interaction/DoubleClick
00199         // http://www.vtk.org/Wiki/VTK/Examples/Cxx/Interaction/PointPicker
00200         if(this->CurrentRenderer && this->CurrentRenderer->GetLayer() == 1)
00201         {
00202                 this->NumberOfClicks++;
00203                 int pickPosition[2];
00204                 this->GetInteractor()->GetEventPosition(pickPosition);
00205                 int xdist = pickPosition[0] - this->PreviousPosition[0];
00206                 int ydist = pickPosition[1] - this->PreviousPosition[1];
00207 
00208                 this->PreviousPosition[0] = pickPosition[0];
00209                 this->PreviousPosition[1] = pickPosition[1];
00210 
00211                 int moveDistance = (int)sqrt((double)(xdist*xdist + ydist*ydist));
00212 
00213                 // Reset numClicks - If mouse moved further than resetPixelDistance
00214                 if(moveDistance > this->ResetPixelDistance)
00215                 {
00216                         this->NumberOfClicks = 1;
00217                 }
00218 
00219                 if(this->NumberOfClicks >= 2)
00220                 {
00221                         this->NumberOfClicks = 0;
00222                         this->Interactor->GetPicker()->Pick(pickPosition[0], pickPosition[1],
00223                                         0,  // always zero.
00224                                         this->CurrentRenderer);
00225                         double picked[3];
00226                         this->Interactor->GetPicker()->GetPickPosition(picked);
00227                         UDEBUG("Double clicked! Picked value: %f %f %f", picked[0], picked[1], picked[2]);
00228                         if(this->GetInteractor()->GetControlKey()==0)
00229                         {
00230                                 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
00231                                 UASSERT(camera);
00232                                 double position[3];
00233                                 double focal[3];
00234                                 camera->GetPosition(position[0], position[1], position[2]);
00235                                 camera->GetFocalPoint(focal[0], focal[1], focal[2]);
00236                                 //camera->SetPosition (position[0] + (picked[0]-focal[0]), position[1] + (picked[1]-focal[1]), position[2] + (picked[2]-focal[2]));
00237                                 camera->SetFocalPoint (picked[0], picked[1], picked[2]);
00238                                 camera->OrthogonalizeViewUp();
00239 
00240                                 if (this->AutoAdjustCameraClippingRange)
00241                                 {
00242                                         this->CurrentRenderer->ResetCameraClippingRange();
00243                                 }
00244 
00245                                 if (this->Interactor->GetLightFollowCamera())
00246                                 {
00247                                         this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
00248                                 }
00249                         }
00250                         else if(viewer_)
00251                         {
00252                                 viewer_->removeText("interactor_pose");
00253                                 viewer_->removeLine("interactor_line");
00254                                 viewer_->removeCloud("interactor_points");
00255                                 viewer_->removeLine("interactor_ray");
00256                                 viewer_->removeText("interactor_ray_text");
00257                                 viewer_->removeCloud("interactor_points_alt");
00258                                 viewer_->removeLine("interactor_ray_alt");
00259                                 viewer_->removeText("interactor_ray_text_alt");
00260                                 PreviousMeasure[0] = 0.0f;
00261                                 PreviousMeasure[1] = 0.0f;
00262                                 PreviousMeasure[2] = 0.0f;
00263                         }
00264                 }
00265                 else if(this->GetInteractor()->GetControlKey() && viewer_)
00266                 {
00267                         this->Interactor->GetPicker()->Pick(pickPosition[0], pickPosition[1],
00268                                         0,  // always zero.
00269                                         this->CurrentRenderer);
00270                         double picked[3];
00271                         this->Interactor->GetPicker()->GetPickPosition(picked);
00272 
00273                         UDEBUG("Shift clicked! Picked value: %f %f %f", picked[0], picked[1], picked[2]);
00274 
00275                         float textSize = 0.05;
00276 
00277                         viewer_->removeCloud("interactor_points");
00278                         pointsHolder_->clear();
00279                         pcl::PointXYZRGB pt(255,0,0);
00280                         pt.x = picked[0];
00281                         pt.y = picked[1];
00282                         pt.z = picked[2];
00283                         pointsHolder_->push_back(pt);
00284 
00285                         viewer_->removeLine("interactor_ray");
00286                         viewer_->removeText("interactor_ray_text");
00287 
00288                         if(     PreviousMeasure[0] != 0.0f && PreviousMeasure[1] != 0.0f && PreviousMeasure[2] != 0.0f &&
00289                                 viewer_->getAddedLines().find("interactor_line") == viewer_->getAddedLines().end())
00290                         {
00291                                 viewer_->addOrUpdateLine("interactor_line",
00292                                                 Transform(PreviousMeasure[0], PreviousMeasure[1], PreviousMeasure[2], 0, 0, 0),
00293                                                 Transform(picked[0], picked[1], picked[2], 0, 0, 0),
00294                                                 Qt::red);
00295                                 pt.x = PreviousMeasure[0];
00296                                 pt.y = PreviousMeasure[1];
00297                                 pt.z = PreviousMeasure[2];
00298                                 pointsHolder_->push_back(pt);
00299 
00300                                 Eigen::Vector3f v(picked[0]-PreviousMeasure[0], picked[1]-PreviousMeasure[1], picked[2]-PreviousMeasure[2]);
00301                                 float n = v.norm();
00302                                 v/=n;
00303                                 v *= n/2.0f;
00304                                 viewer_->addOrUpdateText("interactor_pose", uFormat("%.2f m", n),
00305                                                 Transform(PreviousMeasure[0]+v[0], PreviousMeasure[1]+v[1],PreviousMeasure[2]+v[2], 0, 0, 0),
00306                                                 textSize,
00307                                                 Qt::red);
00308                         }
00309                         else
00310                         {
00311                                 viewer_->removeText("interactor_pose");
00312                                 viewer_->removeLine("interactor_line");
00313                         }
00314                         PreviousMeasure[0] = picked[0];
00315                         PreviousMeasure[1] = picked[1];
00316                         PreviousMeasure[2] = picked[2];
00317 
00318                         viewer_->addCloud("interactor_points", pointsHolder_);
00319                         viewer_->setCloudPointSize("interactor_points", 15);
00320                         viewer_->setCloudOpacity("interactor_points", 0.5);
00321                 }
00322         }
00323 
00324         // Forward events
00325         PCLVisualizerInteractorStyle::OnLeftButtonDown();
00326 }
00327 
00328 } /* namespace rtabmap */


rtabmap
Author(s): Mathieu Labbe
autogenerated on Thu Jun 6 2019 21:59:19