00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "QmitkBoundingObjectWidget.h"
00019
00020 #include <mitkCone.h>
00021 #include <mitkCylinder.h>
00022 #include <mitkCuboid.h>
00023 #include <mitkEllipsoid.h>
00024 #include <mitkAffineInteractor.h>
00025 #include <mitkGlobalInteraction.h>
00026 #include <mitkNodePredicateProperty.h>
00027 #include <mitkLine.h>
00028
00029 #include <QPushButton>
00030 #include <QCheckBox>
00031 #include <QBoxLayout>
00032 #include <QStringList>
00033 #include <QInputDialog>
00034
00035
00036 QmitkBoundingObjectWidget::QmitkBoundingObjectWidget (QWidget* parent, Qt::WindowFlags f ):QWidget( parent, f ),
00037 m_DataStorage(NULL),
00038 m_lastSelectedItem(NULL),
00039 m_ItemNodeMap()
00040 {
00041
00042 QBoxLayout* mainLayout = new QVBoxLayout(this);
00043
00044 QHBoxLayout* buttonLayout = new QHBoxLayout();
00045
00046 QStringList boList;
00047 boList << tr("add") << tr("cube") << tr("cone") << tr("ellipse") << tr("cylinder");
00048 m_addComboBox = new QComboBox();
00049 m_addComboBox->addItems(boList);
00050 m_addComboBox->setItemIcon(1, QIcon(":/QmitkSegmentationConstructionKitView/Cube_48.png"));
00051 m_addComboBox->setItemIcon(2, QIcon(":/QmitkSegmentationConstructionKitView/Pyramid_48.png"));
00052 m_addComboBox->setItemIcon(3, QIcon(":/QmitkSegmentationConstructionKitView/Ellipsoid_48.png"));
00053 m_addComboBox->setItemIcon(4, QIcon(":/QmitkSegmentationConstructionKitView/Cylinder_48.png"));
00054
00055 buttonLayout->addWidget(m_addComboBox);
00056
00057 m_DelButton = new QPushButton("del");
00058 buttonLayout->addWidget(m_DelButton);
00059
00060
00061 m_SaveButton = new QPushButton("save");
00062 buttonLayout->addWidget(m_SaveButton);
00063 m_SaveButton->setEnabled(false);
00064
00065 m_LoadButton = new QPushButton("load");
00066 buttonLayout->addWidget(m_LoadButton);
00067 m_LoadButton->setEnabled(false);
00068
00069 m_TreeWidget = new QTreeWidget(this);
00070 m_TreeWidget->setColumnCount(3);
00071 QStringList sList;
00072 sList << tr("name") << tr("inverted") << tr("visible");
00073 m_TreeWidget->setHeaderLabels(sList);
00074 m_TreeWidget->setColumnWidth(0, 250);
00075 m_TreeWidget->setColumnWidth(1, 50);
00076 m_TreeWidget->setColumnWidth(2, 50);
00077 m_TreeWidget->setAutoScroll(true);
00078 m_TreeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
00079
00080 mainLayout->addWidget(m_TreeWidget);
00081 mainLayout->addLayout(buttonLayout);
00082
00083 connect( m_addComboBox , SIGNAL(currentIndexChanged(int)), this, SLOT(CreateBoundingObject(int)) );
00084 connect( m_TreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(SelectionChanged()) );
00085
00086
00087 connect( m_DelButton, SIGNAL(clicked()), this, SLOT(OnDelButtonClicked()) );
00088
00089 connect(m_TreeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnItemDoubleClicked(QTreeWidgetItem*, int)) );
00090 connect(m_TreeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(OnItemDataChanged(QTreeWidgetItem*, int)) );
00091
00092 }
00093
00094 QmitkBoundingObjectWidget::~QmitkBoundingObjectWidget()
00095 {
00096
00097 }
00098
00099 void QmitkBoundingObjectWidget::setEnabled(bool flag)
00100 {
00101 ItemNodeMapType::iterator it = m_ItemNodeMap.begin();
00102 while( it != m_ItemNodeMap.end())
00103 {
00104 mitk::DataNode* node = it->second;
00105 QTreeWidgetItem* item = it->first;
00106
00107 if (flag)
00108 node->SetVisibility(item->checkState(2));
00109 else
00110 node->SetVisibility(flag);
00111 ++it;
00112 }
00113
00114 QWidget::setEnabled(flag);
00115 mitk::RenderingManager::GetInstance()->RequestUpdateAll();
00116 }
00117
00118 void QmitkBoundingObjectWidget::SelectionChanged()
00119 {
00120
00121 QList<QTreeWidgetItem*> selectedItems = m_TreeWidget->selectedItems();
00122 if (selectedItems.size() < 1)
00123 return;
00124
00125 QTreeWidgetItem* selectedItem = selectedItems.first();
00126
00127 if (selectedItem == m_lastSelectedItem)
00128 return;
00129
00130 if (m_lastSelectedItem != NULL)
00131 {
00132 m_TreeWidget->closePersistentEditor(m_lastSelectedItem, 0);
00133
00134 ItemNodeMapType::iterator it = m_ItemNodeMap.find(m_lastSelectedItem);
00135 if (it != m_ItemNodeMap.end())
00136 {
00137 mitk::DataNode* last_node = it->second;
00138 mitk::AffineInteractor::Pointer last_interactor = dynamic_cast<mitk::AffineInteractor*> (last_node->GetInteractor());
00139
00140 if (last_interactor)
00141 mitk::GlobalInteraction::GetInstance()->RemoveInteractor(last_interactor);
00142 }
00143 }
00144
00145 ItemNodeMapType::iterator it = m_ItemNodeMap.find(selectedItem);
00146 if (it == m_ItemNodeMap.end())
00147 return;
00148
00149 mitk::DataNode* new_node = it->second;
00150
00151 mitk::AffineInteractor::Pointer new_interactor = mitk::AffineInteractor::New("AffineInteractions ctrl-drag", new_node);
00152 new_node->SetInteractor(new_interactor);
00153
00154 mitk::GlobalInteraction::GetInstance()->AddInteractor(new_interactor);
00155
00156 m_lastSelectedItem = selectedItem;
00157 }
00158
00159 void QmitkBoundingObjectWidget::AddItem(mitk::DataNode* node)
00160 {
00161 mitk::BoundingObject* boundingObject;
00162
00163 boundingObject = dynamic_cast<mitk::BoundingObject*> (node->GetData());
00164
00165 std::string name;
00166 node->GetStringProperty("name", name);
00167
00168 if (boundingObject)
00169 {
00170 QTreeWidgetItem* item = new QTreeWidgetItem();
00171 item->setData(0, Qt::EditRole, QString::fromLocal8Bit(name.c_str()));
00172 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
00173
00174
00175 item->setData(1, Qt::CheckStateRole, tr(""));
00176 item->setCheckState(1, Qt::Unchecked);
00177
00178
00179 item->setData(2, Qt::CheckStateRole, tr(""));
00180 item->setCheckState(2, Qt::Checked);
00181
00182 m_TreeWidget->addTopLevelItem(item);
00183
00184 m_ItemNodeMap.insert(std::make_pair(item, node));
00185
00186 m_TreeWidget->selectAll();
00187 QList<QTreeWidgetItem*> items = m_TreeWidget->selectedItems();
00188 for( int i = 0; i<items.size(); i++)
00189 {
00190 m_TreeWidget->setItemSelected(items.at(i), false);
00191 }
00192
00193 m_TreeWidget->setItemSelected(item, true);
00194
00195
00196 }
00197 else
00198 MITK_ERROR << name << " is not a bounding object or does not exist in data storage" << endl;
00199 }
00200
00201 void QmitkBoundingObjectWidget::OnItemDoubleClicked(QTreeWidgetItem* item, int col)
00202 {
00203 if (col == 0)
00204 {
00205 m_TreeWidget->openPersistentEditor(item, col);
00206 }
00207 }
00208
00209 void QmitkBoundingObjectWidget::OnItemDataChanged(QTreeWidgetItem *item, int col)
00210 {
00211 if (m_ItemNodeMap.size() < 1)
00212 return;
00213
00214 ItemNodeMapType::iterator it = m_ItemNodeMap.find(item);
00215 if (it == m_ItemNodeMap.end())
00216 return;
00217
00218 mitk::DataNode* node = it->second;
00219
00220
00221 if (col == 0)
00222 {
00223 m_TreeWidget->closePersistentEditor(item, col);
00224 node->SetName(item->text(0).toLocal8Bit().data());
00225 }
00226
00227 else if (col == 1)
00228 {
00229 mitk::BoundingObject* boundingObject = dynamic_cast<mitk::BoundingObject*> (node->GetData());
00230 if (boundingObject)
00231 boundingObject->SetPositive(!(item->checkState(1)));
00232 emit BoundingObjectsChanged(tr("bounding objects"));
00233 }
00234
00235 else if (col == 2)
00236 {
00237 node->SetVisibility(item->checkState(2));
00238 }
00239
00240 mitk::RenderingManager::GetInstance()->RequestUpdateAll();
00241
00242
00243 }
00244
00245 void QmitkBoundingObjectWidget::RemoveItem()
00246 {
00247
00248 QList <QTreeWidgetItem*> selectedItems = m_TreeWidget->selectedItems();
00249 QTreeWidgetItem* item = selectedItems.first();
00250 QString str = item->text(0);
00251
00252 ItemNodeMapType::iterator it = m_ItemNodeMap.find(item);
00253
00254 if (it == m_ItemNodeMap.end())
00255 return;
00256
00257 mitk::DataNode* node = it->second;
00258 mitk::BoundingObject* boundingObject;
00259
00260 if (node)
00261 {
00262 boundingObject = dynamic_cast<mitk::BoundingObject*> (node->GetData());
00263 if (boundingObject)
00264 {
00265
00266 m_TreeWidget->takeTopLevelItem(m_TreeWidget->indexOfTopLevelItem(item));
00267 m_ItemNodeMap.erase(m_ItemNodeMap.find(item));
00268 m_DataStorage->Remove(node);
00269 }
00270 }
00271 }
00272
00273 mitk::BoundingObject::Pointer QmitkBoundingObjectWidget::GetSelectedBoundingObject()
00274 {
00275 mitk::BoundingObject* boundingObject;
00276 mitk::DataNode* node = this->GetSelectedBoundingObjectNode();
00277
00278 if (node)
00279 {
00280 boundingObject = dynamic_cast<mitk::BoundingObject*> (node->GetData());
00281 if (boundingObject)
00282 return boundingObject;
00283 }
00284 return NULL;
00285 }
00286
00287 void QmitkBoundingObjectWidget::SetDataStorage(mitk::DataStorage* dataStorage)
00288 {
00289 m_DataStorage = dataStorage;
00290 }
00291
00292 mitk::DataStorage* QmitkBoundingObjectWidget::GetDataStorage()
00293 {
00294 return m_DataStorage;
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 void QmitkBoundingObjectWidget::OnDelButtonClicked()
00308 {
00309 RemoveItem();
00310 }
00311
00312 void QmitkBoundingObjectWidget::CreateBoundingObject(int type)
00313 {
00314
00315
00316 mitk::Point3D pos;
00317 mitk::RenderingManager::RenderWindowVector windows = mitk::RenderingManager::GetInstance()->GetAllRegisteredRenderWindows();
00318
00319
00320 const mitk::PlaneGeometry *plane1 =
00321 mitk::BaseRenderer::GetInstance(windows.at(0))->GetSliceNavigationController()->GetCurrentPlaneGeometry();
00322 const mitk::PlaneGeometry *plane2 =
00323 mitk::BaseRenderer::GetInstance(windows.at(1))->GetSliceNavigationController()->GetCurrentPlaneGeometry();
00324 const mitk::PlaneGeometry *plane3 =
00325 mitk::BaseRenderer::GetInstance(windows.at(2))->GetSliceNavigationController()->GetCurrentPlaneGeometry();
00326
00327 mitk::Line3D line;
00328 if ( (plane1 != NULL) && (plane2 != NULL)
00329 && (plane1->IntersectionLine( plane2, line )) )
00330 {
00331 if ( !((plane3 != NULL)
00332 && (plane3->IntersectionPoint( line, pos ))) )
00333 {
00334 return;
00335 }
00336 }
00337
00338 if (type != 0)
00339 {
00340 mitk::BoundingObject::Pointer boundingObject;
00341 static int i = 1;
00342 QString name;
00343 name.setNum(i);
00344
00345 switch (type-1)
00346 {
00347 case CUBOID:
00348 boundingObject = mitk::Cuboid::New();
00349 name.prepend("Cube_");
00350 break;
00351 case CONE:
00352 boundingObject = mitk::Cone::New();
00353 name.prepend("Cone_");
00354 break;
00355 case ELLIPSOID:
00356 boundingObject = mitk::Ellipsoid::New();
00357 name.prepend("Ellipse_");
00358 break;
00359 case CYLINDER:
00360 boundingObject = mitk::Cylinder::New();
00361 name.prepend("Cylinder_");
00362 break;
00363 default:
00364 return;
00365 break;
00366 }
00367 i++;
00368 m_addComboBox->setCurrentIndex(0);
00369
00370
00371 mitk::Vector3D size;
00372 size.Fill(10);
00373 boundingObject->GetGeometry()->SetSpacing( size );
00374
00375 boundingObject->GetGeometry()->Translate(pos.GetVectorFromOrigin());
00376 boundingObject->GetTimeSlicedGeometry()->UpdateInformation();
00377
00378
00379 mitk::DataNode::Pointer node = mitk::DataNode::New();
00380 node->SetData( boundingObject);
00381 node->SetProperty("name", mitk::StringProperty::New( name.toLocal8Bit().data()));
00382 node->SetProperty("color", mitk::ColorProperty::New(0.0, 0.0, 1.0));
00383 node->SetProperty("opacity", mitk::FloatProperty::New(0.7));
00384 node->SetProperty("bounding object", mitk::BoolProperty::New(true));
00385 node->SetProperty("helper object", mitk::BoolProperty::New(true));
00386
00387 m_DataStorage->Add(node);
00388
00389 mitk::RenderingManager::GetInstance()->RequestUpdateAll();
00390
00391 emit BoundingObjectsChanged(tr("bounding objects"));
00392
00393 AddItem(node);
00394 }
00395 }
00396
00397 mitk::DataNode::Pointer QmitkBoundingObjectWidget::GetAllBoundingObjects()
00398 {
00399 mitk::DataNode::Pointer boundingObjectGroupNode = mitk::DataNode::New();
00400 mitk::BoundingObjectGroup::Pointer boundingObjectGroup = mitk::BoundingObjectGroup::New();
00401 boundingObjectGroup->SetCSGMode(mitk::BoundingObjectGroup::Union);
00402
00403 mitk::NodePredicateProperty::Pointer prop = mitk::NodePredicateProperty::New("bounding object", mitk::BoolProperty::New(true));
00404 mitk::DataStorage::SetOfObjects::ConstPointer allBO = m_DataStorage->GetSubset(prop);
00405
00406 for (mitk::DataStorage::SetOfObjects::const_iterator it = allBO->begin(); it != allBO->end(); ++it)
00407 {
00408 mitk::DataNode::Pointer node = *it;
00409 mitk::BoundingObject::Pointer boundingObject = dynamic_cast<mitk::BoundingObject*> (node->GetData());
00410 if (boundingObject)
00411 boundingObjectGroup->AddBoundingObject(boundingObject);
00412 }
00413
00414 boundingObjectGroupNode->SetData(boundingObjectGroup);
00415
00416 if (boundingObjectGroup->GetCount() >0)
00417 return boundingObjectGroupNode;
00418
00419 return NULL;
00420 }
00421
00422 mitk::DataNode::Pointer QmitkBoundingObjectWidget::GetSelectedBoundingObjectNode()
00423 {
00424 QList <QTreeWidgetItem*> selectedItems = m_TreeWidget->selectedItems();
00425 if (selectedItems.size() <1)
00426 return NULL;
00427
00428 QTreeWidgetItem* item = selectedItems.first();
00429 mitk::DataNode* node = m_ItemNodeMap.find(item)->second;
00430
00431 return node;
00432 }