Skip to content
Snippets Groups Projects
Commit 26b107b6 authored by Julian Heinze's avatar Julian Heinze
Browse files

New Dialog for the creation of VoxelGrids from a 3D mesh

parent d9be87b7
No related branches found
No related tags found
No related merge requests found
...@@ -45,6 +45,7 @@ set(SOURCES ...@@ -45,6 +45,7 @@ set(SOURCES
StationTreeView.cpp StationTreeView.cpp
SurfaceExtractionDialog.cpp SurfaceExtractionDialog.cpp
TranslateDataDialog.cpp TranslateDataDialog.cpp
Vtu2GridDialog.cpp
) )
set(HEADERS set(HEADERS
...@@ -98,6 +99,7 @@ set(HEADERS ...@@ -98,6 +99,7 @@ set(HEADERS
StationTreeModel.h StationTreeModel.h
StationTreeView.h StationTreeView.h
SurfaceExtractionDialog.h SurfaceExtractionDialog.h
Vtu2GridDialog.h
) )
# Visual Studio folder # Visual Studio folder
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Vtu2Grid</class>
<widget class="QDialog" name="Vtu2Grid">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>253</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>30</x>
<y>200</y>
<width>341</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QComboBox" name="meshListBox">
<property name="geometry">
<rect>
<x>100</x>
<y>30</y>
<width>274</width>
<height>28</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
<widget class="QLabel" name="meshListLabel">
<property name="geometry">
<rect>
<x>0</x>
<y>30</y>
<width>110</width>
<height>28</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>110</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string> Select mesh:</string>
</property>
</widget>
<widget class="QGroupBox" name="VoxelSizeBox">
<property name="geometry">
<rect>
<x>70</x>
<y>90</y>
<width>281</width>
<height>69</height>
</rect>
</property>
<property name="title">
<string>Voxel size</string>
</property>
<widget class="QLabel" name="xLengthLabel">
<property name="geometry">
<rect>
<x>12</x>
<y>32</y>
<width>16</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>x:</string>
</property>
</widget>
<widget class="QLineEdit" name="xlineEdit">
<property name="geometry">
<rect>
<x>31</x>
<y>32</y>
<width>51</width>
<height>25</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="yLengthLabel">
<property name="geometry">
<rect>
<x>100</x>
<y>32</y>
<width>16</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>y:</string>
</property>
</widget>
<widget class="QLineEdit" name="ylineEdit">
<property name="geometry">
<rect>
<x>120</x>
<y>32</y>
<width>51</width>
<height>25</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="zLengthLabel">
<property name="geometry">
<rect>
<x>190</x>
<y>32</y>
<width>16</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>z:</string>
</property>
</widget>
<widget class="QLineEdit" name="zlineEdit">
<property name="geometry">
<rect>
<x>210</x>
<y>32</y>
<width>51</width>
<height>25</height>
</rect>
</property>
</widget>
</widget>
<widget class="QLabel" name="expectedVoxelLabel">
<property name="geometry">
<rect>
<x>40</x>
<y>170</y>
<width>291</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Expected Voxel: </string>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Vtu2Grid</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Vtu2Grid</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
/**
* \file
* \date 2023-05-11
* \brief Implementation of the Vtu2GridDialog class.
*
* \copyright
* Copyright (c) 2012-2023, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "Vtu2GridDialog.h"
#include <vtkXMLUnstructuredGridWriter.h>
#include <QStringList>
#include <QStringListModel>
#include <string>
#include "Base/StrictDoubleValidator.h"
#include "GeoLib/AABB.h"
#include "MeshLib/IO/writeMeshToFile.h"
#include "MeshLib/Mesh.h"
#include "MeshLib/Node.h"
#include "MeshLib/Vtk/VtkMappedMeshSource.h"
#include "MeshModel.h"
#include "MeshToolsLib/MeshGenerators/MeshGenerator.h"
#include "MeshToolsLib/MeshGenerators/VoxelGridFromMesh.h"
Vtu2GridDialog::Vtu2GridDialog(MeshModel& mesh_model, QDialog* parent)
: QDialog(parent), _mesh_model(mesh_model)
{
setupUi(this);
QStringList MeshList;
for (int model_index = 0; model_index < mesh_model.rowCount();
++model_index)
{
auto const* mesh = mesh_model.getMesh(mesh_model.index(model_index, 0));
MeshList.append(QString::fromStdString(mesh->getName()));
}
if (MeshList.empty())
{
MeshList.append("[No Mesh available.]");
this->expectedVoxelLabel->setText("Expected Voxel: undefined");
}
_allMeshes.setStringList(MeshList);
this->meshListBox->addItems(_allMeshes.stringList());
this->xlineEdit->setFocus();
}
void Vtu2GridDialog::updateExpectedVoxel()
{
QString const xin = this->xlineEdit->text();
QString const yin = this->ylineEdit->text();
QString const zin = this->zlineEdit->text();
bool ok;
double const xinput = xin.toDouble();
double const yinput = (yin.toDouble(&ok)) ? yin.toDouble() : xin.toDouble();
double const zinput = (zin.toDouble(&ok)) ? zin.toDouble() : xin.toDouble();
if (_allMeshes.stringList()[0] == "[No Mesh available.]")
{
this->expectedVoxelLabel->setText("approximated Voxel: undefined");
return;
}
if (xin.isEmpty() || xinput == 0)
{
this->expectedVoxelLabel->setText("approximated Voxel: undefined");
return;
}
auto* const _mesh(
_mesh_model.getMesh(this->meshListBox->currentText().toStdString()));
auto const& nodes = _mesh->getNodes();
GeoLib::AABB const aabb(nodes.cbegin(), nodes.cend());
auto const min = aabb.getMinPoint();
auto const max = aabb.getMaxPoint();
double const expectedVoxel = (max[0] - min[0]) * (max[1] - min[1]) *
(max[2] - min[2]) / xinput / yinput / zinput;
int const exponent = std::floor(std::log10(abs(expectedVoxel)));
this->expectedVoxelLabel->setText(
"approximated Voxel = " +
QString::number(std::round(expectedVoxel / std::pow(10, exponent))) +
" x 10^" + QString::number(exponent));
}
void Vtu2GridDialog::on_xlineEdit_textChanged()
{
updateExpectedVoxel();
}
void Vtu2GridDialog::on_ylineEdit_textChanged()
{
updateExpectedVoxel();
}
void Vtu2GridDialog::on_zlineEdit_textChanged()
{
updateExpectedVoxel();
}
void Vtu2GridDialog::accept()
{
using namespace MeshToolsLib::MeshGenerator;
if (this->meshListBox->currentText().toStdString() ==
"[No Mesh available.]")
{
OGSError::box(
"Please specify the input meshes. It has to be a 3D mesh.");
return;
}
QString const xin = this->xlineEdit->text();
QString const yin = this->ylineEdit->text();
QString const zin = this->zlineEdit->text();
bool ok;
if (!xin.toDouble(&ok))
{
OGSError::box(
"At least the x-length of a voxel must be specified.\n If "
"y-/z-input "
"are not specified, equal to 0, or not a real number, they are "
"treated as "
"the x-input.");
return;
}
double const xinput = xin.toDouble();
double const yinput = (yin.toDouble(&ok)) ? yin.toDouble() : xin.toDouble();
double const zinput = (zin.toDouble(&ok)) ? zin.toDouble() : xin.toDouble();
std::array<double, 3> const cellsize = {xinput, yinput, zinput};
auto _mesh(
_mesh_model.getMesh(this->meshListBox->currentText().toStdString()));
if (_mesh->MeshLib::Mesh::getDimension() < 3)
{
OGSError::box("The dimension of the mesh has to be 3.");
return;
}
vtkNew<MeshLib::VtkMappedMeshSource> vtkSource;
vtkSource->SetMesh(_mesh);
vtkSource->Update();
vtkSmartPointer<vtkUnstructuredGrid> mesh = vtkSource->GetOutput();
double* const bounds = mesh->GetBounds();
MathLib::Point3d const min(
std::array<double, 3>{bounds[0], bounds[2], bounds[4]});
MathLib::Point3d const max(
std::array<double, 3>{bounds[1], bounds[3], bounds[5]});
std::array<double, 3> ranges = {max[0] - min[0], max[1] - min[1],
max[2] - min[2]};
if (ranges[0] < 0 || ranges[1] < 0 || ranges[2] < 0)
{
OGSError::box(
"The range (max-min of the bounding box) is not allowed to be < 0");
}
std::array<std::size_t, 3> const dims =
VoxelGridFromMesh::getNumberOfVoxelPerDimension(ranges, cellsize);
std::unique_ptr<MeshLib::Mesh> grid(
generateRegularHexMesh(dims[0], dims[1], dims[2], cellsize[0],
cellsize[1], cellsize[2], min, "grid"));
std::vector<int> const tmp_ids =
VoxelGridFromMesh::assignCellIds(mesh, min, dims, cellsize);
std::vector<int>& cell_ids =
*grid->getProperties().createNewPropertyVector<int>(
VoxelGridFromMesh::cell_id_name, MeshLib::MeshItemType::Cell, 1);
std::copy(tmp_ids.cbegin(), tmp_ids.cend(), std::back_inserter(cell_ids));
if (!VoxelGridFromMesh::removeUnusedGridCells(mesh, grid))
{
return;
}
VoxelGridFromMesh::mapMeshArraysOntoGrid(mesh, grid);
if (mesh == nullptr)
{
OGSError::box("The VoxelGrid is faulty"); // write name of layer.
return;
}
_mesh_model.addMesh(grid.release());
this->done(QDialog::Accepted);
}
std::vector<std::string> Vtu2GridDialog::getSelectedObjects(QStringList list)
{
std::vector<std::string> indexList;
std::transform(list.begin(), list.end(), std::back_inserter(indexList),
[](auto const& index) { return index.toStdString(); });
return indexList;
}
\ No newline at end of file
/**
* \file
* \date 2023-04-26
* \brief Definition of the Vtu2GridDialog class.
*
* \copyright
* Copyright (c) 2012-2023, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#pragma once
#include <QDialog>
#include <QStringListModel>
#include <memory>
#include "MeshLib/Elements/ElementErrorCode.h"
#include "ui_Vtu2Grid.h"
class MeshModel;
/*
* \brief A dialog window for calling methods to create a 3D Voxelgrid from
* multiple 2D vtu meshes
*/
class Vtu2GridDialog : public QDialog, private Ui_Vtu2Grid
{
Q_OBJECT
public:
explicit Vtu2GridDialog(MeshModel& mesh_model,
QDialog* parent = nullptr);
private:
std::vector<std::string> getSelectedObjects(QStringList list);
MeshModel& _mesh_model;
QStringListModel _allMeshes;
private slots:
/// Instructions if the OK-Button has been pressed.
void accept() override;
/// Instructions if the Cancel-Button has been pressed.
void reject() override { this->done(QDialog::Rejected); };
/// Instructions if the ">>-button" has been pressed.
/// Instructions if the ↑-button" has been pressed.
void updateExpectedVoxel();
void on_xlineEdit_textChanged();
void on_ylineEdit_textChanged();
void on_zlineEdit_textChanged();
};
...@@ -80,6 +80,7 @@ ...@@ -80,6 +80,7 @@
#include "DataView/MeshElementRemovalDialog.h" #include "DataView/MeshElementRemovalDialog.h"
#include "DataView/MeshQualitySelectionDialog.h" #include "DataView/MeshQualitySelectionDialog.h"
#include "DataView/TranslateDataDialog.h" #include "DataView/TranslateDataDialog.h"
#include "DataView/Vtu2GridDialog.h"
#ifdef OGS_USE_NETCDF #ifdef OGS_USE_NETCDF
#include "VtkVis/NetCdfConfigureDialog.h" #include "VtkVis/NetCdfConfigureDialog.h"
#endif // OGS_USE_NETCDF #endif // OGS_USE_NETCDF
...@@ -1364,6 +1365,16 @@ void MainWindow::showLayers2GridDialog() ...@@ -1364,6 +1365,16 @@ void MainWindow::showLayers2GridDialog()
dlg.exec(); dlg.exec();
} }
void MainWindow::showVtu2GridDialog()
{
if (_meshModel == nullptr)
{
OGSError::box("The supplied mesh_model is not existing.");
}
auto dlg = Vtu2GridDialog(*_meshModel);
dlg.exec();
}
void MainWindow::convertPointsToStations(std::string const& geo_name) void MainWindow::convertPointsToStations(std::string const& geo_name)
{ {
std::string stn_name = geo_name + " Stations"; std::string stn_name = geo_name + " Stations";
......
...@@ -107,6 +107,7 @@ protected slots: ...@@ -107,6 +107,7 @@ protected slots:
void showMeshQualitySelectionDialog( void showMeshQualitySelectionDialog(
MeshLib::VtkMappedMeshSource* mshSource); MeshLib::VtkMappedMeshSource* mshSource);
void showVisalizationPrefsDialog(); void showVisalizationPrefsDialog();
void showVtu2GridDialog();
void updateDataViews(); void updateDataViews();
void writeGeometryToFile(QString gliName, QString fileName); void writeGeometryToFile(QString gliName, QString fileName);
void writeStationListToFile(QString listName, QString fileName); void writeStationListToFile(QString listName, QString fileName);
......
...@@ -132,6 +132,7 @@ ...@@ -132,6 +132,7 @@
<addaction name="actionDiagram_Viewer"/> <addaction name="actionDiagram_Viewer"/>
<addaction name="actionFEM_Test"/> <addaction name="actionFEM_Test"/>
<addaction name="actionTranslating_Data"/> <addaction name="actionTranslating_Data"/>
<addaction name="action3D_mesh_to_Voxelgrid"/>
<addaction name="actionCreate_a_Voxelgrid"/> <addaction name="actionCreate_a_Voxelgrid"/>
</widget> </widget>
<widget class="QMenu" name="menuHelp"> <widget class="QMenu" name="menuHelp">
...@@ -476,6 +477,11 @@ ...@@ -476,6 +477,11 @@
<string>Translating Data</string> <string>Translating Data</string>
</property> </property>
</action> </action>
<action name="action3D_mesh_to_Voxelgrid">
<property name="text">
<string>3D mesh to Voxelgrid</string>
</property>
</action>
<action name="actionCreate_a_Voxelgrid"> <action name="actionCreate_a_Voxelgrid">
<property name="text"> <property name="text">
<string>Create a Voxelgrid from Layers</string> <string>Create a Voxelgrid from Layers</string>
...@@ -779,6 +785,22 @@ ...@@ -779,6 +785,22 @@
</hint> </hint>
</hints> </hints>
</connection> </connection>
<connection>
<sender>action3D_mesh_to_Voxelgrid</sender>
<signal>triggered()</signal>
<receiver>MainWindowClass</receiver>
<slot>showVtu2GridDialog()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>400</x>
<y>372</y>
</hint>
</hints>
</connection>
<connection> <connection>
<sender>actionCreate_Structured_Mesh</sender> <sender>actionCreate_Structured_Mesh</sender>
<signal>triggered()</signal> <signal>triggered()</signal>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment