00001
00002
00003
00004
00005
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
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
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,
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
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
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
00193 PCLVisualizerInteractorStyle::OnMouseMove();
00194 }
00195
00196 void CloudViewerInteractorStyle::OnLeftButtonDown()
00197 {
00198
00199
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
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,
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
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,
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
00325 PCLVisualizerInteractorStyle::OnLeftButtonDown();
00326 }
00327
00328 }