00001 #include <pcl/apps/cloud_composer/qt.h>
00002 #include <pcl/apps/cloud_composer/cloud_view.h>
00003 #include <pcl/apps/cloud_composer/cloud_composer.h>
00004 #include <pcl/apps/cloud_composer/project_model.h>
00005
00006 #include <pcl/apps/cloud_composer/point_selectors/selection_event.h>
00007 #include <pcl/apps/cloud_composer/point_selectors/manipulation_event.h>
00008
00009 pcl::cloud_composer::CloudView::CloudView (QWidget* parent)
00010 : QWidget (parent)
00011 {
00012 vis_.reset (new pcl::visualization::PCLVisualizer ("", false));
00013 vis_->getInteractorStyle ()->setKeyboardModifier (pcl::visualization::INTERACTOR_KB_MOD_SHIFT);
00014
00015 qvtk_ = new QVTKWidget (this);
00016 qvtk_->SetRenderWindow (vis_->getRenderWindow ());
00017 initializeInteractorSwitch ();
00018 vis_->setupInteractor (qvtk_->GetInteractor (), qvtk_->GetRenderWindow (), style_switch_);
00019
00020 QGridLayout *mainLayout = new QGridLayout (this);
00021 mainLayout-> addWidget (qvtk_,0,0);
00022 }
00023
00024 pcl::cloud_composer::CloudView::CloudView (ProjectModel* model, QWidget* parent)
00025 : QWidget (parent)
00026 {
00027 model_ = model;
00028 vis_.reset (new pcl::visualization::PCLVisualizer ("", false));
00029
00030
00031 qvtk_ = new QVTKWidget (this);
00032 qvtk_->SetRenderWindow (vis_->getRenderWindow ());
00033 initializeInteractorSwitch ();
00034 vis_->setupInteractor (qvtk_->GetInteractor (), qvtk_->GetRenderWindow (), style_switch_);
00035 setModel(model);
00036
00037 QGridLayout *mainLayout = new QGridLayout (this);
00038 mainLayout-> addWidget (qvtk_,0,0);
00039 }
00040
00041 pcl::cloud_composer::CloudView::CloudView (const CloudView& to_copy)
00042 : QWidget ()
00043 , vis_ (to_copy.vis_)
00044 , model_ (to_copy.model_)
00045 , qvtk_ (to_copy.qvtk_)
00046 {
00047 }
00048
00049
00050 pcl::cloud_composer::CloudView::~CloudView ()
00051 {
00052 }
00053
00054 void
00055 pcl::cloud_composer::CloudView::setModel (ProjectModel* new_model)
00056 {
00057 model_ = new_model;
00058
00059 connectSignalsAndSlots();
00060
00061 qvtk_->show();
00062 qvtk_->update ();
00063
00064
00065 }
00066
00067 void
00068 pcl::cloud_composer::CloudView::connectSignalsAndSlots()
00069 {
00070 connect (model_, SIGNAL (itemChanged (QStandardItem*)),
00071 this, SLOT (itemChanged (QStandardItem*)));
00072 connect (model_, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
00073 this, SLOT (rowsInserted (const QModelIndex&, int, int)));
00074 connect (model_, SIGNAL (rowsAboutToBeRemoved (const QModelIndex, int, int)),
00075 this, SLOT (rowsAboutToBeRemoved(const QModelIndex,int,int)));
00076 }
00077
00078 void
00079 pcl::cloud_composer::CloudView::refresh ()
00080 {
00081 qvtk_->update ();
00082 }
00083
00084 void
00085 pcl::cloud_composer::CloudView::itemChanged (QStandardItem* changed_item)
00086 {
00087 qDebug () << "Item Changed - Redrawing!";
00088 CloudComposerItem* item = dynamic_cast<CloudComposerItem*> (changed_item);
00089 if (item)
00090 {
00091 item->paintView (vis_);
00092 }
00093 qvtk_->update ();
00094 }
00095
00096
00097
00098 void
00099 pcl::cloud_composer::CloudView::rowsInserted (const QModelIndex& parent, int start, int end)
00100 {
00101 QStandardItem* parent_item;
00102
00103 if (!parent.isValid())
00104 parent_item = model_->invisibleRootItem();
00105 else
00106 parent_item = model_->itemFromIndex (parent);
00107 QString project_name = model_->getName ();
00108 for (int row = start; row <= end; ++row)
00109 {
00110 QStandardItem* new_item = parent_item->child(row);
00111 CloudComposerItem* item = dynamic_cast<CloudComposerItem*> (new_item);
00112 item = dynamic_cast<CloudComposerItem*> (new_item);
00113 if (item)
00114 item->paintView (vis_);
00115
00116
00117
00118 if (new_item->rowCount () > 0)
00119 rowsInserted(new_item->index(),0,new_item->rowCount ()-1);
00120 }
00121
00122 qvtk_->update ();
00123
00124 }
00125
00126 void
00127 pcl::cloud_composer::CloudView::rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end)
00128 {
00129 QStandardItem* parent_item;
00130
00131 if (!parent.isValid())
00132 parent_item = model_->invisibleRootItem();
00133 else
00134 parent_item = model_->itemFromIndex (parent);
00135 QString project_name = model_->getName ();
00136
00137 for (int row = start; row <= end; ++row)
00138 {
00139 QStandardItem* item_to_remove = parent_item->child(row);
00140 if (item_to_remove)
00141 qDebug () << "Removing "<<item_to_remove->text ();
00142 CloudComposerItem* item = dynamic_cast<CloudComposerItem*> (item_to_remove);
00143 if (item )
00144 item->removeFromView (vis_);
00145
00146
00147
00148 if (item_to_remove->rowCount () > 0)
00149 rowsAboutToBeRemoved(item_to_remove->index(),0,item_to_remove->rowCount ()-1);
00150 }
00151 qvtk_->update ();
00152 }
00153
00154
00155 void
00156 pcl::cloud_composer::CloudView::paintEvent (QPaintEvent*)
00157 {
00158 qvtk_->update ();
00159 }
00160
00161 void
00162 pcl::cloud_composer::CloudView::resizeEvent (QResizeEvent*)
00163 {
00164 qvtk_->update ();
00165 }
00166
00167 void
00168 pcl::cloud_composer::CloudView::selectedItemChanged (const QItemSelection & selected, const QItemSelection & deselected)
00169 {
00170 QModelIndexList current_indices = selected.indexes ();
00171 QModelIndexList previous_indices = deselected.indexes ();
00172 foreach (QModelIndex previous, previous_indices)
00173 {
00174 if (previous.isValid ())
00175 {
00176 QStandardItem* previous_item = model_->itemFromIndex (previous);
00177 if (previous_item->type () == CloudComposerItem::CLOUD_ITEM || previous_item->type () == CloudComposerItem::NORMALS_ITEM)
00178 {
00179 vis_->setPointCloudSelected (false, previous_item->data (ItemDataRole::ITEM_ID).toString ().toStdString ());
00180 }
00181 }
00182 }
00183 foreach (QModelIndex current, current_indices)
00184 {
00185 if (current.isValid ())
00186 {
00187 QStandardItem* current_item = model_->itemFromIndex (current);
00188 if (current_item->type () == CloudComposerItem::CLOUD_ITEM || current_item->type () == CloudComposerItem::NORMALS_ITEM)
00189 {
00190 vis_->setPointCloudSelected (true, current_item->data (ItemDataRole::ITEM_ID).toString ().toStdString ());
00191 }
00192 }
00193 }
00194 qvtk_->update ();
00195 }
00196
00197 void
00198 pcl::cloud_composer::CloudView::dataChanged (const QModelIndex & topLeft, const QModelIndex & bottomRight)
00199 {
00200
00201
00202 }
00203
00206 void
00207 pcl::cloud_composer::CloudView::setAxisVisibility (bool visible)
00208 {
00209 if (visible)
00210 {
00211 qDebug () << "Adding coordinate system!";
00212 vis_->addOrientationMarkerWidgetAxes ( qvtk_->GetInteractor() );
00213 }
00214 else
00215 {
00216 vis_->removeOrientationMarkerWidgetAxes ();
00217 }
00218
00219 qvtk_->update ();
00220 }
00221
00222 void
00223 pcl::cloud_composer::CloudView::addOrientationMarkerWidgetAxes ()
00224 {
00225 if (!axes_widget_)
00226 {
00227 vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor>::New ();
00228
00229 axes_widget_ = vtkSmartPointer<vtkOrientationMarkerWidget>::New ();
00230 axes_widget_->SetOutlineColor ( 0.9300, 0.5700, 0.1300 );
00231 axes_widget_->SetOrientationMarker( axes );
00232 axes_widget_->SetInteractor( qvtk_->GetInteractor () );
00233 axes_widget_->SetViewport( 0.0, 0.0, 0.4, 0.4 );
00234 axes_widget_->SetEnabled( 1 );
00235 axes_widget_->InteractiveOn();
00236 }
00237 else
00238 {
00239 axes_widget_->SetEnabled (true);
00240 }
00241
00242 }
00243
00244
00245 void
00246 pcl::cloud_composer::CloudView::removeOrientationMarkerWidgetAxes ()
00247 {
00248 if (axes_widget_)
00249 {
00250 axes_widget_->SetEnabled (false);
00251 }
00252
00253
00254 }
00255
00258 void
00259 pcl::cloud_composer::CloudView::initializeInteractorSwitch ()
00260 {
00261 style_switch_ = vtkSmartPointer<InteractorStyleSwitch>::New();
00262 style_switch_->initializeInteractorStyles (vis_, model_);
00263 style_switch_->SetInteractor (qvtk_->GetInteractor ());
00264 style_switch_->setCurrentInteractorStyle (interactor_styles::PCL_VISUALIZER);
00265
00266
00267 connections_ = vtkSmartPointer<vtkEventQtSlotConnect>::New();
00268 connections_->Connect (style_switch_->getInteractorStyle (interactor_styles::RECTANGULAR_FRUSTUM),
00269 interactor_events::SELECTION_COMPLETE_EVENT,
00270 this,
00271 SLOT (selectionCompleted (vtkObject*, unsigned long, void*, void*)));
00272
00273 connections_->Connect (style_switch_->getInteractorStyle (interactor_styles::CLICK_TRACKBALL),
00274 interactor_events::MANIPULATION_COMPLETE_EVENT,
00275 this,
00276 SLOT (manipulationCompleted (vtkObject*, unsigned long, void*, void*)));
00277 }
00278
00279 void
00280 pcl::cloud_composer::CloudView::setInteractorStyle (interactor_styles::INTERACTOR_STYLES style)
00281 {
00282 style_switch_->setCurrentInteractorStyle (style);
00283 }
00284
00285 void
00286 pcl::cloud_composer::CloudView::selectionCompleted (vtkObject* caller, unsigned long event_id, void* client_data, void* call_data)
00287 {
00288 boost::shared_ptr<SelectionEvent> selected (static_cast<SelectionEvent*> (call_data));
00289
00290 if (selected)
00291 {
00292 qDebug () << "Selection Complete! - Num points="<<selected->getNumPoints();
00293 model_->setPointSelection (selected);
00294 style_switch_->setCurrentInteractorStyle (interactor_styles::PCL_VISUALIZER);
00295 }
00296 }
00297
00298
00299 void
00300 pcl::cloud_composer::CloudView::manipulationCompleted (vtkObject* caller, unsigned long event_id, void* client_data, void* call_data)
00301 {
00302 boost::shared_ptr<ManipulationEvent> manip_event (static_cast<ManipulationEvent*> (call_data));
00303
00304 if (manip_event)
00305 {
00306 qDebug () << "Manipulation event received in cloud view!";
00307 model_->manipulateClouds (manip_event);
00308
00309 }
00310 }