OGS
VtkVisPipelineView.cpp
Go to the documentation of this file.
1 
15 // ** INCLUDES **
16 #include "VtkVisPipelineView.h"
17 
18 #include <vtkDataSetMapper.h>
19 #include <vtkProp3D.h>
20 
21 #include <QAbstractItemModel>
22 #include <QContextMenuEvent>
23 #include <QFileDialog>
24 #include <QHeaderView>
25 #include <QMenu>
26 #include <QMessageBox>
27 #include <QSettings>
28 
29 #include "Base/CheckboxDelegate.h"
30 #include "Base/OGSError.h"
31 #include "MeshLib/Mesh.h"
34 #include "VtkVisPipeline.h"
35 #include "VtkVisPipelineItem.h"
36 #include "VtkVisPointSetItem.h"
37 
38 // image to mesh conversion
39 #include <vtkDataObject.h>
40 #include <vtkGenericDataObjectReader.h>
41 #include <vtkImageData.h>
42 #include <vtkSmartPointer.h>
43 #include <vtkTransformFilter.h>
44 #include <vtkUnstructuredGrid.h>
45 #include <vtkUnstructuredGridAlgorithm.h>
46 #include <vtkXMLUnstructuredGridReader.h>
47 
48 #include "MeshFromRasterDialog.h"
49 #include "VtkGeoImageSource.h"
50 
52  : QTreeView(parent)
53 {
54  this->setItemsExpandable(false);
55  auto* checkboxDelegate = new CheckboxDelegate(this);
56  this->setItemDelegateForColumn(1, checkboxDelegate);
57  this->header()->setStretchLastSection(true);
58  this->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
59 }
60 
61 void VtkVisPipelineView::setModel(QAbstractItemModel* model)
62 {
63  QTreeView::setModel(model);
64 
65  // Move Visible checkbox to the left.
66  // This is done here because at constructor time there aren't any sections.
67  this->header()->moveSection(1, 0);
68 }
69 
70 void VtkVisPipelineView::contextMenuEvent(QContextMenuEvent* event)
71 {
72  QModelIndex index = selectionModel()->currentIndex();
73  if (index.isValid())
74  {
75  // check object type
76  VtkVisPipelineItem* item = static_cast<VtkVisPipelineItem*>(
77  static_cast<VtkVisPipeline*>(this->model())
78  ->getItem(this->selectionModel()->currentIndex()));
79  int objectType =
80  item->algorithm()->GetOutputDataObject(0)->GetDataObjectType();
81  VtkAlgorithmProperties* vtkProps = item->getVtkProperties();
82  bool isSourceItem =
83  !(this->selectionModel()->currentIndex().parent().isValid());
84 
85  QMenu menu;
86  QAction* addFilterAction = menu.addAction("Add filter...");
87 
88  if (objectType == VTK_IMAGE_DATA)
89  {
90  // this exception is needed as image object are only displayed in
91  // the vis-pipeline
92  isSourceItem = false;
93  QAction* addMeshingAction =
94  menu.addAction("Convert Image to Mesh...");
95  connect(addMeshingAction, SIGNAL(triggered()), this,
97  }
98  else
99  {
100  QAction* addLUTAction = menu.addAction("Add color table...");
101  connect(addLUTAction, SIGNAL(triggered()), this,
102  SLOT(addColorTable()));
103  }
104 
105  if (objectType == VTK_UNSTRUCTURED_GRID)
106  {
107  QAction* addConvertToMeshAction =
108  menu.addAction("Convert to Mesh...");
109  connect(addConvertToMeshAction, SIGNAL(triggered()), this,
110  SLOT(convertVTKToOGSMesh()));
111  }
112  menu.addSeparator();
113  QAction* exportVtkAction = menu.addAction("Export as VTK");
114 
115  if (!isSourceItem || vtkProps->IsRemovable())
116  {
117  menu.addSeparator();
118  QAction* removeAction = menu.addAction("Remove");
119  connect(removeAction, SIGNAL(triggered()), this,
121  }
122 
123  connect(addFilterAction, SIGNAL(triggered()), this,
124  SLOT(addPipelineFilterItem()));
125  connect(exportVtkAction, SIGNAL(triggered()), this,
127 
128  menu.exec(event->globalPos());
129  }
130 }
131 
133 {
134  QSettings settings;
135  QModelIndex idx = this->selectionModel()->currentIndex();
136  QString filename = QFileDialog::getSaveFileName(
137  this, "Export object to vtk-file",
138  settings.value("lastExportedFileDirectory").toString(),
139  "VTK file (*.*)");
140  if (!filename.isEmpty())
141  {
142  static_cast<VtkVisPipelineItem*>(
143  static_cast<VtkVisPipeline*>(this->model())->getItem(idx))
144  ->writeToFile(filename.toStdString());
145  QDir dir = QDir(filename);
146  settings.setValue("lastExportedFileDirectory", dir.absolutePath());
147  }
148 }
149 
151 {
152  emit requestRemovePipelineItem(selectionModel()->currentIndex());
153 }
154 
156 {
157  emit requestAddPipelineFilterItem(selectionModel()->currentIndex());
158 }
159 
161 {
163  if (dlg.exec() != QDialog::Accepted)
164  {
165  return;
166  }
167 
168  vtkSmartPointer<vtkAlgorithm> algorithm =
169  static_cast<VtkVisPipelineItem*>(
170  static_cast<VtkVisPipeline*>(this->model())
171  ->getItem(this->selectionModel()->currentIndex()))
172  ->algorithm();
173 
174  vtkSmartPointer<VtkGeoImageSource> imageSource =
175  VtkGeoImageSource::SafeDownCast(algorithm);
176  double origin[3];
177  imageSource->GetOutput()->GetOrigin(origin);
178  double spacing[3];
179  imageSource->GetOutput()->GetSpacing(spacing);
180 
181  auto mesh = MeshLib::RasterToMesh::convert(
182  imageSource->GetOutput(), origin, spacing[0], dlg.getElementSelection(),
183  dlg.getIntensitySelection(), dlg.getArrayName());
184  if (mesh)
185  {
186  mesh->setName(dlg.getMeshName());
187  emit meshAdded(mesh.release());
188  }
189  else
190  {
191  OGSError::box("Error creating mesh.");
192  }
193 }
194 
196 {
197  VtkVisPipelineItem* item = static_cast<VtkVisPipelineItem*>(
198  static_cast<VtkVisPipeline*>(this->model())
199  ->getItem(this->selectionModel()->currentIndex()));
200  vtkSmartPointer<vtkAlgorithm> algorithm = item->algorithm();
201 
202  vtkUnstructuredGrid* grid(nullptr);
203  vtkUnstructuredGridAlgorithm* ugAlg =
204  vtkUnstructuredGridAlgorithm::SafeDownCast(algorithm);
205  if (ugAlg)
206  {
207  grid = ugAlg->GetOutput();
208  }
209  else
210  {
211  // for old filetypes
212  vtkGenericDataObjectReader* dataReader =
213  vtkGenericDataObjectReader::SafeDownCast(algorithm);
214  if (dataReader)
215  {
216  grid = vtkUnstructuredGrid::SafeDownCast(dataReader->GetOutput());
217  }
218  else
219  {
220  // for new filetypes
221  vtkXMLUnstructuredGridReader* xmlReader =
222  vtkXMLUnstructuredGridReader::SafeDownCast(algorithm);
223  grid = vtkUnstructuredGrid::SafeDownCast(xmlReader->GetOutput());
224  }
225  }
226  MeshLib::Mesh* mesh =
228  mesh->setName(item->data(0).toString().toStdString());
229  emit meshAdded(mesh);
230 }
231 
232 void VtkVisPipelineView::selectionChanged(const QItemSelection& selected,
233  const QItemSelection& deselected)
234 {
235  QTreeView::selectionChanged(selected, deselected);
236 
237  if (selected.empty())
238  {
239  return;
240  }
241 
242  QModelIndex index = *selected.indexes().begin();
243  if (index.isValid())
244  {
245  auto* item = static_cast<VtkVisPipelineItem*>(index.internalPointer());
246  emit actorSelected(item->actor());
247  emit itemSelected(item);
248  if (item->transformFilter())
249  {
250  emit dataObjectSelected(vtkDataObject::SafeDownCast(
251  item->transformFilter()->GetOutputDataObject(0)));
252  }
253  }
254  else
255  {
256  emit actorSelected(nullptr);
257  emit itemSelected(nullptr);
258  emit dataObjectSelected(nullptr);
259  }
260 }
261 
262 void VtkVisPipelineView::selectItem(vtkProp3D* actor)
263 {
264  this->selectItem(
265  static_cast<VtkVisPipeline*>(this->model())->getIndex(actor));
266 }
267 
268 void VtkVisPipelineView::selectItem(const QModelIndex& index)
269 {
270  if (!index.isValid())
271  {
272  return;
273  }
274 
275  QItemSelectionModel* selectionModel = this->selectionModel();
276  selectionModel->clearSelection();
277  selectionModel->select(index, QItemSelectionModel::Select);
278 }
279 
281 {
282  VtkVisPipelineItem* item(static_cast<VtkVisPipelineItem*>(
283  static_cast<VtkVisPipeline*>(this->model())
284  ->getItem(this->selectionModel()->currentIndex())));
285  const QString array_name = item->GetActiveAttribute();
286 
287  QSettings settings;
288  QString filename = QFileDialog::getOpenFileName(
289  this, "Select color table",
290  settings.value("lastOpenedLutFileDirectory").toString(),
291  "Color table files (*.xml);;");
292  QFileInfo fi(filename);
293 
294  if (fi.suffix().toLower() == "xml")
295  {
296  auto* pointSetItem = dynamic_cast<VtkVisPointSetItem*>(item);
297  if (pointSetItem)
298  {
299  VtkAlgorithmProperties* props = pointSetItem->getVtkProperties();
300  if (props)
301  {
302  props->SetLookUpTable(array_name, filename);
303  item->SetActiveAttribute(array_name);
304  emit requestViewUpdate();
305  }
306  }
307  else
308  {
309  QMessageBox::warning(nullptr,
310  "Color lookup table could not be applied.",
311  "Color lookup tables can only be applied to "
312  "VtkVisPointSetItem.");
313  }
314  QDir dir = QDir(filename);
315  settings.setValue("lastOpenedLutFileDirectory", dir.absolutePath());
316  }
317 }
Definition of the CheckboxDelegate class.
Definition of the MeshFromRasterDialog class.
Definition of the Mesh class.
Definition of the OGSError class.
Definition of the VtkGeoImageSource class.
Definition of the VtkMeshConverter class.
Definition of the VtkVisPipelineItem class.
Definition of the VtkVisPipelineView class.
Definition of the VtkVisPipeline class.
Definition of the VtkVisPointSetItem class.
CheckboxDelegate modifies a model view to display boolean values as checkboxes.
A dialog for specifying the parameters to construct a mesh based on a raster.
std::string getMeshName() const
MeshLib::MeshElemType getElementSelection() const
std::string getArrayName() const
MeshLib::UseIntensityAs getIntensitySelection() const
void setName(const std::string &name)
Changes the name of the mesh.
Definition: Mesh.h:107
static std::unique_ptr< MeshLib::Mesh > convert(GeoLib::Raster const &raster, MeshElemType elem_type, UseIntensityAs intensity_type, std::string const &array_name="Colour")
static MeshLib::Mesh * convertUnstructuredGrid(vtkUnstructuredGrid *grid, std::string const &mesh_name="vtkUnstructuredGrid")
Converts a vtkUnstructuredGrid object to a Mesh.
static void box(const QString &e)
Definition: OGSError.cpp:23
Contains properties for the visualization of objects as VtkVisPipelineItems.
void SetLookUpTable(const QString &array_name, vtkLookupTable *lut)
Sets a colour lookup table for the given scalar array of the VtkVisPipelineItem.
bool IsRemovable() const
Is this algorithm removable from the pipeline (view).
An item in the VtkVisPipeline containing a graphic object to be visualized.
vtkAlgorithm * algorithm() const
Returns the algorithm object.
VtkAlgorithmProperties * getVtkProperties() const
Returns the VtkAlgorithmProperties.
virtual QString GetActiveAttribute() const
QVariant data(int column) const override
virtual void SetActiveAttribute(const QString &str)
void setModel(QAbstractItemModel *model) override
Overridden to set model specific header properties.
VtkVisPipelineView(QWidget *parent=nullptr)
Constructor.
void requestRemovePipelineItem(QModelIndex)
void meshAdded(MeshLib::Mesh *)
void dataObjectSelected(vtkDataObject *)
void requestAddPipelineFilterItem(QModelIndex)
void exportSelectedPipelineItemAsVtk()
Exports the currently selected item as a VTK file.
void convertVTKToOGSMesh()
Calls the conversion method for making a vtk grid an ogs mesh.
void actorSelected(vtkProp3D *)
void selectItem(vtkProp3D *actor)
void addColorTable()
Adds a color lookup table to the current scalar array of the selected pipeline item.
void itemSelected(VtkVisPipelineItem *)
void contextMenuEvent(QContextMenuEvent *event) override
Creates a menu on right-clicking on an item.
void showImageToMeshConversionDialog()
Calls the dialog to.
void addPipelineFilterItem()
Sends a requestAddPipelineFilterItem() signal to add a filter.
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override
Emits itemSelected() signals when an items was selected.
VtkVisPipeline manages the VTK visualization. It is a TreeModel and provides functions for adding and...
An item in the VtkVisPipeline containing a point set object to be visualized.
void writeToFile(std::string const &id_area_fname, std::string const &csv_fname, std::vector< std::pair< std::size_t, double >> const &ids_and_areas, std::vector< MeshLib::Node * > const &mesh_nodes)