00001 #include <pcl/apps/cloud_composer/qt.h>
00002 #include <pcl/apps/cloud_composer/cloud_composer.h>
00003 #include <pcl/apps/cloud_composer/project_model.h>
00004 #include <pcl/apps/cloud_composer/cloud_viewer.h>
00005 #include <pcl/apps/cloud_composer/cloud_view.h>
00006 #include <pcl/apps/cloud_composer/item_inspector.h>
00007 #include <pcl/apps/cloud_composer/commands.h>
00008 #include <pcl/apps/cloud_composer/tool_interface/tool_factory.h>
00009 #include <pcl/apps/cloud_composer/tool_interface/abstract_tool.h>
00010 #include <pcl/apps/cloud_composer/toolbox_model.h>
00011 #include <pcl/apps/cloud_composer/signal_multiplexer.h>
00012 #include <pcl/apps/cloud_composer/point_selectors/interactor_style_switch.h>
00013
00015 pcl::cloud_composer::ComposerMainWindow::ComposerMainWindow (QWidget *parent)
00016 : QMainWindow (parent)
00017 {
00018 setupUi (this);
00019
00020 this->setCorner (Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
00021 this->setCorner (Qt::BottomRightCorner, Qt::RightDockWidgetArea);
00022
00023
00024 qRegisterMetaType<pcl::PCLPointCloud2::Ptr> ("PCLPointCloud2Ptr");
00025 qRegisterMetaType<GeometryHandler::ConstPtr> ("GeometryHandlerConstPtr");
00026 qRegisterMetaType<ColorHandler::ConstPtr> ("ColorHandlerConstPtr");
00027 qRegisterMetaType<Eigen::Vector4f> ("EigenVector4f");
00028 qRegisterMetaType<Eigen::Quaternionf> ("EigenQuaternionf");
00029 qRegisterMetaType<ProjectModel> ("ProjectModel");
00030 qRegisterMetaType<CloudView> ("CloudView");
00031 qRegisterMetaType<ConstItemList> ("ConstComposerItemList");
00032
00033 current_model_ = 0;
00034
00035 multiplexer_ = new SignalMultiplexer (this);
00036
00037 initializeCloudBrowser ();
00038 initializeCloudViewer ();
00039 initializeItemInspector ();
00040 initializeToolBox ();
00041 initializePlugins ();
00042
00043 undo_group_ = new QUndoGroup (this);
00044 undo_view_->setGroup (undo_group_);
00045
00046
00047
00048 connectFileActions ();
00049 connectEditActions ();
00050 connectViewActions ();
00051
00052 }
00053
00054 pcl::cloud_composer::ComposerMainWindow::~ComposerMainWindow ()
00055 {
00056 foreach (ProjectModel* to_delete, name_model_map_.values ())
00057 to_delete->deleteLater ();
00058 }
00059
00060 void
00061 pcl::cloud_composer::ComposerMainWindow::connectFileActions ()
00062 {
00063
00064
00065 }
00066
00067 void
00068 pcl::cloud_composer::ComposerMainWindow::connectEditActions ()
00069 {
00070
00071 QAction* action_temp = undo_group_->createUndoAction (this);
00072 action_temp->setShortcut (action_undo_->shortcut ());
00073 menuEdit->insertAction (action_redo_, action_temp);
00074 menuEdit->removeAction (action_undo_);
00075 action_undo_ = action_temp;
00076
00077 action_temp = undo_group_->createRedoAction (this);
00078 action_temp->setShortcut (action_redo_->shortcut ());
00079 menuEdit->insertAction (action_redo_, action_temp);
00080 menuEdit->removeAction (action_redo_);
00081 action_redo_ = action_temp;
00082
00083 multiplexer_->connect (action_clear_selection_, SIGNAL (triggered ()), SLOT (clearSelection ()));
00084
00085 multiplexer_->connect (action_delete_, SIGNAL (triggered ()), SLOT (deleteSelectedItems ()));
00086 multiplexer_->connect (SIGNAL (deleteAvailable (bool)), action_delete_, SLOT (setEnabled (bool)));
00087
00088 multiplexer_->connect (this, SIGNAL (insertNewCloudFromFile()), SLOT (insertNewCloudFromFile()));
00089 multiplexer_->connect (this, SIGNAL (insertNewCloudFromRGBandDepth()), SLOT (insertNewCloudFromRGBandDepth()));
00090 multiplexer_->connect (this, SIGNAL (saveSelectedCloudToFile()), SLOT (saveSelectedCloudToFile()));
00091
00092
00093 mouse_style_group_ = new QActionGroup (this);
00094 mouse_style_group_->addAction (action_trackball_camera_style_);
00095 mouse_style_group_->addAction (action_manipulate_clicked_);
00096 mouse_style_group_->addAction (action_manipulate_selected_);
00097 mouse_style_group_->addAction (action_rectangular_frustum_select_);
00098 mouse_style_group_->setExclusive (true);
00099 multiplexer_->connect (mouse_style_group_, SIGNAL (triggered (QAction*)), SLOT (mouseStyleChanged (QAction*)));
00100 multiplexer_->connect(SIGNAL (mouseStyleState (interactor_styles::INTERACTOR_STYLES)), this, SLOT(setMouseStyleAction(interactor_styles::INTERACTOR_STYLES)));
00101 action_trackball_camera_style_->setData (QVariant::fromValue (interactor_styles::PCL_VISUALIZER));
00102 action_rectangular_frustum_select_->setData (QVariant::fromValue (interactor_styles::RECTANGULAR_FRUSTUM));
00103 action_manipulate_selected_->setData (QVariant::fromValue (interactor_styles::SELECTED_TRACKBALL));
00104 action_manipulate_clicked_->setData (QVariant::fromValue (interactor_styles::CLICK_TRACKBALL));
00105
00106
00107
00108 multiplexer_->connect (action_new_cloud_from_selection_, SIGNAL (triggered ()), SLOT (createNewCloudFromSelection ()));
00109 multiplexer_->connect (SIGNAL (newCloudFromSelectionAvailable (bool)), action_new_cloud_from_selection_, SLOT (setEnabled (bool)));
00110
00111 multiplexer_->connect (action_select_all_, SIGNAL (triggered ()), SLOT (selectAllItems ()));
00112 }
00113
00114 void
00115 pcl::cloud_composer::ComposerMainWindow::setMouseStyleAction (interactor_styles::INTERACTOR_STYLES selected_style)
00116 {
00117 action_trackball_camera_style_->setChecked (false);
00118 action_rectangular_frustum_select_->setChecked (false);
00119 action_manipulate_selected_->setChecked (false);
00120 action_manipulate_clicked_->setChecked (false);
00121
00122 switch (selected_style)
00123 {
00124 case interactor_styles::PCL_VISUALIZER :
00125 action_trackball_camera_style_->setChecked (true);
00126 break;
00127 case interactor_styles::CLICK_TRACKBALL :
00128 action_manipulate_clicked_->setChecked (true);
00129 break;
00130 case interactor_styles::RECTANGULAR_FRUSTUM :
00131 action_rectangular_frustum_select_->setChecked (true);
00132 break;
00133 case interactor_styles::SELECTED_TRACKBALL :
00134 action_manipulate_selected_->setChecked (true);
00135 break;
00136 default :
00137 action_trackball_camera_style_->setChecked (true);
00138
00139 }
00140 }
00141
00142 void
00143 pcl::cloud_composer::ComposerMainWindow::connectViewActions ()
00144 {
00145 multiplexer_->connect (action_show_axes_, SIGNAL (toggled (bool)), SLOT (setAxisVisibility (bool)));
00146 multiplexer_->connect (SIGNAL (axisVisible (bool)), action_show_axes_, SLOT (setChecked (bool)));
00147
00148 }
00149
00150 void
00151 pcl::cloud_composer::ComposerMainWindow::initializeCloudBrowser ()
00152 {
00153 cloud_browser_->setSelectionMode (QAbstractItemView::ExtendedSelection);
00154
00155 cloud_browser_->setStyleSheet("selection-background-color: red;");
00156
00157 }
00158
00159 void
00160 pcl::cloud_composer::ComposerMainWindow::initializeCloudViewer ()
00161 {
00162
00163 connect (cloud_viewer_, SIGNAL (newModelSelected (ProjectModel*)),
00164 this, SLOT (setCurrentModel (ProjectModel*)));
00165
00166 }
00167
00168 void
00169 pcl::cloud_composer::ComposerMainWindow::initializeItemInspector ()
00170 {
00171
00172 }
00173
00174 void
00175 pcl::cloud_composer::ComposerMainWindow::initializeToolBox ()
00176 {
00177 tool_box_model_ = new ToolBoxModel (tool_box_view_, tool_parameter_view_,this);
00178 tool_selection_model_ = new QItemSelectionModel (tool_box_model_);
00179 tool_box_model_->setSelectionModel (tool_selection_model_);
00180
00181 tool_box_view_->setModel (tool_box_model_);
00182 tool_box_view_->setSelectionModel (tool_selection_model_);
00183 tool_box_view_->setIconSize (QSize (32,32));
00184 tool_box_view_->setIndentation (10);
00185
00186 connect ( tool_selection_model_, SIGNAL (currentChanged (const QModelIndex&, const QModelIndex&)),
00187 tool_box_model_, SLOT (selectedToolChanged (const QModelIndex&, const QModelIndex&)));
00188
00189 connect ( tool_box_model_, SIGNAL (enqueueToolAction (AbstractTool*)),
00190 this, SLOT (enqueueToolAction (AbstractTool*)));
00191
00192 connect (this, SIGNAL (activeProjectChanged (ProjectModel*,ProjectModel*)),
00193 tool_box_model_, SLOT (activeProjectChanged (ProjectModel*,ProjectModel*)));
00194
00195
00196 connect ( action_run_tool_, SIGNAL (clicked ()),
00197 tool_box_model_, SLOT (toolAction ()));
00198
00199
00200
00201
00202 }
00203
00204
00205 void
00206 pcl::cloud_composer::ComposerMainWindow::initializePlugins ()
00207 {
00208 QDir plugin_dir = QCoreApplication::applicationDirPath ();
00209 qDebug() << plugin_dir.path ()<< " "<<QDir::cleanPath ("../lib/cloud_composer_plugins");
00210 #if _WIN32
00211 if (!plugin_dir.cd (QDir::cleanPath ("cloud_composer_plugins")))
00212 #else
00213 if (!plugin_dir.cd (QDir::cleanPath ("../lib/cloud_composer_plugins")))
00214 #endif
00215 {
00216 #if _WIN32
00217 if (!plugin_dir.cd (QDir::cleanPath ("cloud_composer_plugins")))
00218 #else
00219 if (!plugin_dir.cd (QDir::cleanPath ("../lib")))
00220 #endif
00221 {
00222 qCritical () << "Could not find plugin tool directory!!!";
00223 }
00224 }
00225 QStringList plugin_filter;
00226 #if _WIN32
00227 plugin_filter << "pcl_cc_tool_*.dll";
00228 #else
00229 plugin_filter << "libpcl_cc_tool_*.so";
00230 #endif
00231 plugin_dir.setNameFilters (plugin_filter);
00232 foreach (QString filename, plugin_dir.entryList (QDir::Files))
00233 {
00234 qDebug () << "Loading " << plugin_dir.relativeFilePath (filename);
00235 QPluginLoader loader (plugin_dir.absoluteFilePath (filename), this);
00236
00237 QObject *plugin = loader.instance ();
00238 ToolFactory* tool_factory = qobject_cast <ToolFactory*> (plugin);
00239 if (tool_factory) {
00240 qWarning () << "Loaded " << tool_factory->getPluginName ();
00241
00242 tool_box_model_->addTool (tool_factory);
00243
00244 }
00245 else{
00246 qDebug() << "Could not load " << plugin_dir.relativeFilePath (filename);
00247 qDebug() << loader.errorString ();
00248 }
00249
00250 }
00251 }
00252
00253
00254
00255 void
00256 pcl::cloud_composer::ComposerMainWindow::setCurrentModel (ProjectModel* model)
00257 {
00258 emit activeProjectChanged (model, current_model_);
00259 current_model_ = model;
00260
00261 cloud_browser_->setModel (current_model_);
00262
00263 cloud_browser_->setSelectionModel (current_model_->getSelectionModel ());
00264
00265 item_inspector_->setModel (current_model_);
00266
00267 undo_group_->setActiveStack (current_model_->getUndoStack ());
00268
00269 multiplexer_->setCurrentObject (current_model_);
00270 }
00271
00272 void
00273 pcl::cloud_composer::ComposerMainWindow::enqueueToolAction (AbstractTool* tool)
00274 {
00275 if (current_model_)
00276 current_model_->enqueueToolAction (tool);
00277 else
00278 QMessageBox::warning (this, "No Project Open!", "Cannot use tool, no project is open!");
00279 }
00281 void
00282 pcl::cloud_composer::ComposerMainWindow::on_action_new_project__triggered ()
00283 {
00284 QString name("unsaved project");
00285
00286 qDebug () << "Creating New Project";
00287 ProjectModel* new_project_model = new ProjectModel (this);
00288
00289 if (name_model_map_.contains (name))
00290 {
00291 int k = 2;
00292 while (name_model_map_.contains (name + tr ("-%1").arg (k)))
00293 ++k;
00294 name = name + tr ("-%1").arg (k);
00295 }
00296
00297 new_project_model->setName (name);
00298
00299 name_model_map_.insert (name,new_project_model);
00300
00301 undo_group_->addStack (new_project_model->getUndoStack ());
00302
00303 cloud_viewer_->addNewProject (new_project_model);
00304
00305 setCurrentModel (new_project_model);
00306
00307
00308 }
00309
00310
00311 void
00312 pcl::cloud_composer::ComposerMainWindow::on_action_open_cloud_as_new_project__triggered ()
00313 {
00314 qDebug () << "Opening cloud as new project";
00315 }
00316
00317 void
00318 pcl::cloud_composer::ComposerMainWindow::on_action_open_project__triggered ()
00319 {
00320 qDebug () << "Opening Project";
00321 }
00322
00323 void
00324 pcl::cloud_composer::ComposerMainWindow::on_action_save_project__triggered ()
00325 {
00326 qDebug () << "Saving Project";
00327 }
00328
00329 void
00330 pcl::cloud_composer::ComposerMainWindow::on_action_save_project_as__triggered ()
00331 {
00332 qDebug () << "Saving Project As...";
00333 }
00334
00335 void
00336 pcl::cloud_composer::ComposerMainWindow::on_action_save_selected_cloud__triggered ()
00337 {
00338 if (current_model_)
00339 emit saveSelectedCloudToFile();
00340 else
00341 QMessageBox::warning (this, "No Project Open!", "Cannot save cloud, no project is open!");
00342
00343 }
00344
00345 void
00346 pcl::cloud_composer::ComposerMainWindow::on_action_exit__triggered ()
00347 {
00348 qDebug () << "Exiting...";
00349 }
00350
00352 void
00353 pcl::cloud_composer::ComposerMainWindow::on_action_insert_from_file__triggered ()
00354 {
00355 if (!current_model_)
00356 action_new_project_->trigger ();
00357
00358 emit insertNewCloudFromFile ();
00359 }
00360
00361 void
00362 pcl::cloud_composer::ComposerMainWindow::on_action_insert_from_rgb_depth__triggered ()
00363 {
00364 if (!current_model_)
00365 action_new_project_->trigger ();
00366
00367 emit insertNewCloudFromRGBandDepth ();
00368 }
00369
00370
00371 void
00372 pcl::cloud_composer::ComposerMainWindow::on_action_insert_from_openNi_source__triggered ()
00373 {
00374 qDebug () << "Inserting cloud from OpenNi Source...";
00375 }
00376
00377
00378