From 26b107b6377c9a54542f47eeb241b4d846ea9cae Mon Sep 17 00:00:00 2001 From: Julian Heinze Date: Thu, 11 May 2023 11:56:56 +0200 Subject: [PATCH 1/6] New Dialog for the creation of VoxelGrids from a 3D mesh --- .../DataExplorer/DataView/CMakeLists.txt | 2 + .../DataExplorer/DataView/Vtu2Grid.ui | 204 ++++++++++++++++++ .../DataExplorer/DataView/Vtu2GridDialog.cpp | 203 +++++++++++++++++ .../DataExplorer/DataView/Vtu2GridDialog.h | 53 +++++ Applications/DataExplorer/mainwindow.cpp | 11 + Applications/DataExplorer/mainwindow.h | 1 + Applications/DataExplorer/mainwindow.ui | 22 ++ 7 files changed, 496 insertions(+) create mode 100644 Applications/DataExplorer/DataView/Vtu2Grid.ui create mode 100644 Applications/DataExplorer/DataView/Vtu2GridDialog.cpp create mode 100644 Applications/DataExplorer/DataView/Vtu2GridDialog.h diff --git a/Applications/DataExplorer/DataView/CMakeLists.txt b/Applications/DataExplorer/DataView/CMakeLists.txt index 61bec31972b..7fd696947a8 100644 --- a/Applications/DataExplorer/DataView/CMakeLists.txt +++ b/Applications/DataExplorer/DataView/CMakeLists.txt @@ -45,6 +45,7 @@ set(SOURCES StationTreeView.cpp SurfaceExtractionDialog.cpp TranslateDataDialog.cpp + Vtu2GridDialog.cpp ) set(HEADERS @@ -98,6 +99,7 @@ set(HEADERS StationTreeModel.h StationTreeView.h SurfaceExtractionDialog.h + Vtu2GridDialog.h ) # Visual Studio folder diff --git a/Applications/DataExplorer/DataView/Vtu2Grid.ui b/Applications/DataExplorer/DataView/Vtu2Grid.ui new file mode 100644 index 00000000000..0b278ad3143 --- /dev/null +++ b/Applications/DataExplorer/DataView/Vtu2Grid.ui @@ -0,0 +1,204 @@ + + + Vtu2Grid + + + + 0 + 0 + 400 + 253 + + + + Dialog + + + + + 30 + 200 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 100 + 30 + 274 + 28 + + + + + 0 + 0 + + + + + + + 0 + 30 + 110 + 28 + + + + + 110 + 0 + + + + + 110 + 16777215 + + + + Select mesh: + + + + + + 70 + 90 + 281 + 69 + + + + Voxel size + + + + + 12 + 32 + 16 + 17 + + + + x: + + + + + + 31 + 32 + 51 + 25 + + + + + + + 100 + 32 + 16 + 17 + + + + y: + + + + + + 120 + 32 + 51 + 25 + + + + + + + 190 + 32 + 16 + 17 + + + + z: + + + + + + 210 + 32 + 51 + 25 + + + + + + + + 40 + 170 + 291 + 21 + + + + Expected Voxel: + + + + + + + buttonBox + accepted() + Vtu2Grid + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Vtu2Grid + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp b/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp new file mode 100644 index 00000000000..8bafad4d53b --- /dev/null +++ b/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp @@ -0,0 +1,203 @@ +/** + * \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 + +#include +#include +#include + +#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 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 vtkSource; + vtkSource->SetMesh(_mesh); + vtkSource->Update(); + vtkSmartPointer mesh = vtkSource->GetOutput(); + + double* const bounds = mesh->GetBounds(); + MathLib::Point3d const min( + std::array{bounds[0], bounds[2], bounds[4]}); + MathLib::Point3d const max( + std::array{bounds[1], bounds[3], bounds[5]}); + std::array 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 const dims = + VoxelGridFromMesh::getNumberOfVoxelPerDimension(ranges, cellsize); + std::unique_ptr grid( + generateRegularHexMesh(dims[0], dims[1], dims[2], cellsize[0], + cellsize[1], cellsize[2], min, "grid")); + + std::vector const tmp_ids = + VoxelGridFromMesh::assignCellIds(mesh, min, dims, cellsize); + std::vector& cell_ids = + *grid->getProperties().createNewPropertyVector( + 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 Vtu2GridDialog::getSelectedObjects(QStringList list) +{ + std::vector 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 diff --git a/Applications/DataExplorer/DataView/Vtu2GridDialog.h b/Applications/DataExplorer/DataView/Vtu2GridDialog.h new file mode 100644 index 00000000000..db326bd8574 --- /dev/null +++ b/Applications/DataExplorer/DataView/Vtu2GridDialog.h @@ -0,0 +1,53 @@ +/** + * \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 +#include +#include + +#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 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(); +}; diff --git a/Applications/DataExplorer/mainwindow.cpp b/Applications/DataExplorer/mainwindow.cpp index 3acba16408a..91c8c3bb2e2 100644 --- a/Applications/DataExplorer/mainwindow.cpp +++ b/Applications/DataExplorer/mainwindow.cpp @@ -80,6 +80,7 @@ #include "DataView/MeshElementRemovalDialog.h" #include "DataView/MeshQualitySelectionDialog.h" #include "DataView/TranslateDataDialog.h" +#include "DataView/Vtu2GridDialog.h" #ifdef OGS_USE_NETCDF #include "VtkVis/NetCdfConfigureDialog.h" #endif // OGS_USE_NETCDF @@ -1364,6 +1365,16 @@ void MainWindow::showLayers2GridDialog() 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) { std::string stn_name = geo_name + " Stations"; diff --git a/Applications/DataExplorer/mainwindow.h b/Applications/DataExplorer/mainwindow.h index 5dc98f3e78b..7d2ed2a33ed 100644 --- a/Applications/DataExplorer/mainwindow.h +++ b/Applications/DataExplorer/mainwindow.h @@ -107,6 +107,7 @@ protected slots: void showMeshQualitySelectionDialog( MeshLib::VtkMappedMeshSource* mshSource); void showVisalizationPrefsDialog(); + void showVtu2GridDialog(); void updateDataViews(); void writeGeometryToFile(QString gliName, QString fileName); void writeStationListToFile(QString listName, QString fileName); diff --git a/Applications/DataExplorer/mainwindow.ui b/Applications/DataExplorer/mainwindow.ui index 6f783972260..06e2393a585 100644 --- a/Applications/DataExplorer/mainwindow.ui +++ b/Applications/DataExplorer/mainwindow.ui @@ -132,6 +132,7 @@ + @@ -476,6 +477,11 @@ Translating Data + + + 3D mesh to Voxelgrid + + Create a Voxelgrid from Layers @@ -779,6 +785,22 @@ + + action3D_mesh_to_Voxelgrid + triggered() + MainWindowClass + showVtu2GridDialog() + + + -1 + -1 + + + 400 + 372 + + + actionCreate_Structured_Mesh triggered() From 2e9c96afc4a9407cf683dce879b9a62e3df0bf2c Mon Sep 17 00:00:00 2001 From: Julian Heinze Date: Tue, 20 Jun 2023 11:47:32 +0200 Subject: [PATCH 2/6] adjusted mapMeshArraysOntoGrid to cast more data types - long arrays - ogs data arrays --- .../MeshGenerators/VoxelGridFromMesh.cpp | 43 ++++++++++++------- .../MeshGenerators/VoxelGridFromMesh.h | 9 +++- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.cpp b/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.cpp index a8d0284f27b..a7fd1760afc 100644 --- a/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.cpp +++ b/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -126,29 +127,41 @@ void mapArray(MeshLib::Mesh& grid, VTK_TYPE vtk_arr, std::string const& name) arr[j] = vtk_arr->GetValue((*cell_ids)[j]); } +template +bool check_dyncast(MeshLib::Mesh& mesh, + vtkSmartPointer const cell_data, + char const* const name) +{ + using DataArrayType = vtkAOSDataArrayTemplate; + vtkSmartPointer const arr = + dynamic_cast(cell_data->GetArray(name)); + if (!arr) + { + return false; + } + mapArray>(mesh, arr, name); + return true; +} + void mapMeshArraysOntoGrid(vtkSmartPointer const& mesh, std::unique_ptr& grid) { + assert(mesh != nullptr); + assert(grid != nullptr); vtkSmartPointer const cell_data = mesh->GetCellData(); for (int i = 0; i < cell_data->GetNumberOfArrays(); ++i) { - std::string const& name = cell_data->GetArrayName(i); - vtkSmartPointer const dbl_arr = - dynamic_cast(cell_data->GetArray(name.c_str())); - if (dbl_arr) - { - mapArray>(*grid, dbl_arr, - name); - continue; - } - vtkSmartPointer const int_arr = - dynamic_cast(cell_data->GetArray(name.c_str())); - if (int_arr) + auto const name = cell_data->GetArrayName(i); + + if (!(check_dyncast(*grid, cell_data, name) || + check_dyncast(*grid, cell_data, name) || + check_dyncast(*grid, cell_data, name) || + check_dyncast(*grid, cell_data, name))) { - mapArray>(*grid, int_arr, name); - continue; + WARN("Ignoring array '{:s}', array type {:s} not implemented...", + name, + cell_data->GetArray(name)->GetDataTypeAsString()); } - WARN("Ignoring array '{:s}', array type not implemented...", name); } } } // namespace MeshToolsLib::MeshGenerator::VoxelGridFromMesh \ No newline at end of file diff --git a/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.h b/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.h index aef731e64cd..e3761eee99b 100644 --- a/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.h +++ b/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.h @@ -46,7 +46,12 @@ std::vector assignCellIds(vtkSmartPointer const& mesh, // grid has to contain a PropertyVector with the name 'CellIds' bool removeUnusedGridCells(vtkSmartPointer const& mesh, std::unique_ptr& grid); - +// map the cell data of mesh to voxelgrid void mapMeshArraysOntoGrid(vtkSmartPointer const& mesh, std::unique_ptr& grid); -}; // namespace MeshToolsLib::MeshGenerator::VoxelGridFromMesh \ No newline at end of file +// check whether dynamic_cast of cell data is possible the type of cell data to +// map them on voxelgrid +bool check_dyncast(MeshLib::Mesh& mesh, + vtkSmartPointer const cell_data, + char const* const name); +} // namespace MeshToolsLib::MeshGenerator::VoxelGridFromMesh \ No newline at end of file From acadbd8448e8305811a48be645bfd5e07e7bc438 Mon Sep 17 00:00:00 2001 From: Julian Heinze Date: Tue, 20 Jun 2023 16:59:14 +0200 Subject: [PATCH 3/6] extract updateExpectedVoxel() and remove getSelectedObjects() --- .../DataExplorer/DataView/Vtu2GridDialog.cpp | 80 ++++++++++--------- .../DataExplorer/DataView/Vtu2GridDialog.h | 11 +-- 2 files changed, 49 insertions(+), 42 deletions(-) diff --git a/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp b/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp index 8bafad4d53b..fd306b8685f 100644 --- a/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp +++ b/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include "Base/StrictDoubleValidator.h" @@ -53,37 +54,57 @@ Vtu2GridDialog::Vtu2GridDialog(MeshModel& mesh_model, QDialog* parent) this->xlineEdit->setFocus(); } -void Vtu2GridDialog::updateExpectedVoxel() +std::optional> fillXYZ(QString xin, QString yin, + QString zin) { - QString const xin = this->xlineEdit->text(); - QString const yin = this->ylineEdit->text(); - QString const zin = this->zlineEdit->text(); bool ok; + if (!xin.toDouble(&ok)) + { + return std::nullopt; + } 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(); + double const yinput = (yin.toDouble(&ok)) ? yin.toDouble() : xinput; + double const zinput = (zin.toDouble(&ok)) ? zin.toDouble() : xinput; + + if (xinput <= 0 || yinput <= 0 || zinput <= 0) + { + return std::nullopt; + } + + return std::optional>{{xinput, yinput, zinput}}; +} + +Eigen::Vector3d getMeshExtent(MeshLib::Mesh const* _mesh) +{ + auto const& nodes = _mesh->getNodes(); + GeoLib::AABB const aabb(nodes.cbegin(), nodes.cend()); + auto const& min = aabb.getMinPoint(); + auto const& max = aabb.getMaxPoint(); + return max - min; +} +void Vtu2GridDialog::updateExpectedVoxel() +{ if (_allMeshes.stringList()[0] == "[No Mesh available.]") { this->expectedVoxelLabel->setText("approximated Voxel: undefined"); return; } - if (xin.isEmpty() || xinput == 0) + + auto const opt_xyz = + fillXYZ(this->xlineEdit->text(), this->ylineEdit->text(), + this->zlineEdit->text()); + + if (!opt_xyz) { this->expectedVoxelLabel->setText("approximated Voxel: undefined"); return; } - - auto* const _mesh( + auto const& xyz = opt_xyz.value(); + auto const delta = getMeshExtent( _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; + double const expectedVoxel = + (delta[0]) * (delta[1]) * (delta[2]) / xyz[0] / xyz[1] / xyz[2]; int const exponent = std::floor(std::log10(abs(expectedVoxel))); this->expectedVoxelLabel->setText( @@ -118,26 +139,19 @@ void Vtu2GridDialog::accept() return; } - QString const xin = this->xlineEdit->text(); - QString const yin = this->ylineEdit->text(); - QString const zin = this->zlineEdit->text(); + auto opt_xyz = fillXYZ(this->xlineEdit->text(), this->ylineEdit->text(), + this->zlineEdit->text()); - bool ok; - if (!xin.toDouble(&ok)) + if (!opt_xyz) { OGSError::box( - "At least the x-length of a voxel must be specified.\n If " + "At least the x-length of a voxel must be specified and > 0.\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 const cellsize = {xinput, yinput, zinput}; - + auto const& cellsize = opt_xyz.value(); auto _mesh( _mesh_model.getMesh(this->meshListBox->currentText().toStdString())); @@ -192,12 +206,4 @@ void Vtu2GridDialog::accept() _mesh_model.addMesh(grid.release()); this->done(QDialog::Accepted); -} - -std::vector Vtu2GridDialog::getSelectedObjects(QStringList list) -{ - std::vector 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 diff --git a/Applications/DataExplorer/DataView/Vtu2GridDialog.h b/Applications/DataExplorer/DataView/Vtu2GridDialog.h index db326bd8574..b75acde71b8 100644 --- a/Applications/DataExplorer/DataView/Vtu2GridDialog.h +++ b/Applications/DataExplorer/DataView/Vtu2GridDialog.h @@ -31,11 +31,9 @@ class Vtu2GridDialog : public QDialog, private Ui_Vtu2Grid Q_OBJECT public: - explicit Vtu2GridDialog(MeshModel& mesh_model, - QDialog* parent = nullptr); + explicit Vtu2GridDialog(MeshModel& mesh_model, QDialog* parent = nullptr); private: - std::vector getSelectedObjects(QStringList list); MeshModel& _mesh_model; QStringListModel _allMeshes; @@ -44,10 +42,13 @@ private slots: 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. + /// As the x/y/z input changes an estimation of the expected Voxel is given. void updateExpectedVoxel(); void on_xlineEdit_textChanged(); void on_ylineEdit_textChanged(); void on_zlineEdit_textChanged(); }; + +std::optional> fillXYZ(QString xin, + QString yin, + QString zin); \ No newline at end of file From f83e3b2c824655529d17ed555a21233d474a9fa7 Mon Sep 17 00:00:00 2001 From: Julian Heinze Date: Thu, 13 Jul 2023 14:02:56 +0200 Subject: [PATCH 4/6] minor naming fixes and clean-up of header --- .../DataExplorer/DataView/Vtu2GridDialog.cpp | 10 +++++----- .../DataExplorer/DataView/Vtu2GridDialog.h | 6 +----- Applications/DataExplorer/mainwindow.cpp | 4 ++-- Applications/DataExplorer/mainwindow.ui | 18 +++++++++--------- .../MeshGenerators/VoxelGridFromMesh.cpp | 16 +++++++++------- .../MeshGenerators/VoxelGridFromMesh.h | 5 ----- 6 files changed, 26 insertions(+), 33 deletions(-) diff --git a/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp b/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp index fd306b8685f..f0d0fe68d11 100644 --- a/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp +++ b/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp @@ -103,13 +103,13 @@ void Vtu2GridDialog::updateExpectedVoxel() auto const& xyz = opt_xyz.value(); auto const delta = getMeshExtent( _mesh_model.getMesh(this->meshListBox->currentText().toStdString())); - double const expectedVoxel = + double const expected_voxel = (delta[0]) * (delta[1]) * (delta[2]) / xyz[0] / xyz[1] / xyz[2]; - int const exponent = std::floor(std::log10(abs(expectedVoxel))); + int const exponent = std::floor(std::log10(std::abs(expected_voxel))); this->expectedVoxelLabel->setText( "approximated Voxel = " + - QString::number(std::round(expectedVoxel / std::pow(10, exponent))) + + QString::number(std::round(expected_voxel / std::pow(10, exponent))) + " x 10^" + QString::number(exponent)); } @@ -198,9 +198,9 @@ void Vtu2GridDialog::accept() VoxelGridFromMesh::mapMeshArraysOntoGrid(mesh, grid); - if (mesh == nullptr) + if (grid == nullptr) { - OGSError::box("The VoxelGrid is faulty"); // write name of layer. + OGSError::box("No voxelgrid could be created from the mesh."); return; } diff --git a/Applications/DataExplorer/DataView/Vtu2GridDialog.h b/Applications/DataExplorer/DataView/Vtu2GridDialog.h index b75acde71b8..415036bd857 100644 --- a/Applications/DataExplorer/DataView/Vtu2GridDialog.h +++ b/Applications/DataExplorer/DataView/Vtu2GridDialog.h @@ -47,8 +47,4 @@ private slots: void on_xlineEdit_textChanged(); void on_ylineEdit_textChanged(); void on_zlineEdit_textChanged(); -}; - -std::optional> fillXYZ(QString xin, - QString yin, - QString zin); \ No newline at end of file +}; \ No newline at end of file diff --git a/Applications/DataExplorer/mainwindow.cpp b/Applications/DataExplorer/mainwindow.cpp index 91c8c3bb2e2..a4d44f0e706 100644 --- a/Applications/DataExplorer/mainwindow.cpp +++ b/Applications/DataExplorer/mainwindow.cpp @@ -1358,7 +1358,7 @@ void MainWindow::showLayers2GridDialog() { if (_meshModel == nullptr) { - OGSError::box("The supplied mesh_model is not existing."); + OGSError::box("The given mesh model does not exist."); } auto dlg = Layers2GridDialog(*_meshModel); @@ -1369,7 +1369,7 @@ void MainWindow::showVtu2GridDialog() { if (_meshModel == nullptr) { - OGSError::box("The supplied mesh_model is not existing."); + OGSError::box("The given mesh model does not exist."); } auto dlg = Vtu2GridDialog(*_meshModel); dlg.exec(); diff --git a/Applications/DataExplorer/mainwindow.ui b/Applications/DataExplorer/mainwindow.ui index 06e2393a585..529c4568dba 100644 --- a/Applications/DataExplorer/mainwindow.ui +++ b/Applications/DataExplorer/mainwindow.ui @@ -132,8 +132,8 @@ - - + + @@ -477,14 +477,14 @@ Translating Data - + - 3D mesh to Voxelgrid + 3D mesh to voxelgrid - + - Create a Voxelgrid from Layers + Create a voxelgrid from Layers @@ -770,7 +770,7 @@ - actionCreate_a_Voxelgrid + actionCreate_a_voxelgrid triggered() MainWindowClass showLayers2GridDialog() @@ -786,7 +786,7 @@ - action3D_mesh_to_Voxelgrid + action3D_mesh_to_voxelgrid triggered() MainWindowClass showVtu2GridDialog() @@ -800,7 +800,7 @@ 372 - + actionCreate_Structured_Mesh triggered() diff --git a/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.cpp b/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.cpp index a7fd1760afc..d6dcfe2c4c7 100644 --- a/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.cpp +++ b/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.cpp @@ -128,9 +128,11 @@ void mapArray(MeshLib::Mesh& grid, VTK_TYPE vtk_arr, std::string const& name) } template -bool check_dyncast(MeshLib::Mesh& mesh, - vtkSmartPointer const cell_data, - char const* const name) +// check whether dynamic_cast of cell data is possible the type of cell data to +// map them on voxelgrid +bool checkDyncast(MeshLib::Mesh& mesh, + vtkSmartPointer const cell_data, + char const* const name) { using DataArrayType = vtkAOSDataArrayTemplate; vtkSmartPointer const arr = @@ -153,10 +155,10 @@ void mapMeshArraysOntoGrid(vtkSmartPointer const& mesh, { auto const name = cell_data->GetArrayName(i); - if (!(check_dyncast(*grid, cell_data, name) || - check_dyncast(*grid, cell_data, name) || - check_dyncast(*grid, cell_data, name) || - check_dyncast(*grid, cell_data, name))) + if (!(checkDyncast(*grid, cell_data, name) || + checkDyncast(*grid, cell_data, name) || + checkDyncast(*grid, cell_data, name) || + checkDyncast(*grid, cell_data, name))) { WARN("Ignoring array '{:s}', array type {:s} not implemented...", name, diff --git a/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.h b/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.h index e3761eee99b..ea43a90c1c1 100644 --- a/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.h +++ b/MeshToolsLib/MeshGenerators/VoxelGridFromMesh.h @@ -49,9 +49,4 @@ bool removeUnusedGridCells(vtkSmartPointer const& mesh, // map the cell data of mesh to voxelgrid void mapMeshArraysOntoGrid(vtkSmartPointer const& mesh, std::unique_ptr& grid); -// check whether dynamic_cast of cell data is possible the type of cell data to -// map them on voxelgrid -bool check_dyncast(MeshLib::Mesh& mesh, - vtkSmartPointer const cell_data, - char const* const name); } // namespace MeshToolsLib::MeshGenerator::VoxelGridFromMesh \ No newline at end of file From 9586503acb53e4001e7549b0842ef72feb55d34b Mon Sep 17 00:00:00 2001 From: Julian Heinze Date: Thu, 13 Jul 2023 15:36:13 +0200 Subject: [PATCH 5/6] check if dereference is save + remove copy --- .../DataExplorer/DataView/Vtu2GridDialog.cpp | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp b/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp index f0d0fe68d11..6266b3ec407 100644 --- a/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp +++ b/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp @@ -183,14 +183,23 @@ void Vtu2GridDialog::accept() std::unique_ptr grid( generateRegularHexMesh(dims[0], dims[1], dims[2], cellsize[0], cellsize[1], cellsize[2], min, "grid")); + if (grid == nullptr) + { + OGS_FATAL( + "Could not generate regular hex mesh. With parameters dims={} {} " + "{}, " + "cellsize={} {} {}", + dims[0], dims[1], dims[2], cellsize[0], cellsize[1], cellsize[2]); + } - std::vector const tmp_ids = - VoxelGridFromMesh::assignCellIds(mesh, min, dims, cellsize); - std::vector& cell_ids = - *grid->getProperties().createNewPropertyVector( + std::vector* cell_ids = + grid->getProperties().createNewPropertyVector( VoxelGridFromMesh::cell_id_name, MeshLib::MeshItemType::Cell, 1); - std::copy(tmp_ids.cbegin(), tmp_ids.cend(), std::back_inserter(cell_ids)); - + if (cell_ids == nullptr) + { + OGS_FATAL("Could not create cell ids."); + } + *cell_ids = VoxelGridFromMesh::assignCellIds(mesh, min, dims, cellsize); if (!VoxelGridFromMesh::removeUnusedGridCells(mesh, grid)) { return; From a7cc8ac83befd4156c263c5abf2b90ae8aeae140 Mon Sep 17 00:00:00 2001 From: Julian Heinze Date: Thu, 13 Jul 2023 15:46:04 +0200 Subject: [PATCH 6/6] dereference optional for cellsize --- .../DataExplorer/DataView/Vtu2GridDialog.cpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp b/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp index 6266b3ec407..1a864de2757 100644 --- a/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp +++ b/Applications/DataExplorer/DataView/Vtu2GridDialog.cpp @@ -100,11 +100,11 @@ void Vtu2GridDialog::updateExpectedVoxel() this->expectedVoxelLabel->setText("approximated Voxel: undefined"); return; } - auto const& xyz = opt_xyz.value(); + auto const delta = getMeshExtent( _mesh_model.getMesh(this->meshListBox->currentText().toStdString())); - double const expected_voxel = - (delta[0]) * (delta[1]) * (delta[2]) / xyz[0] / xyz[1] / xyz[2]; + double const expected_voxel = (delta[0]) * (delta[1]) * (delta[2]) / + (*opt_xyz)[0] / (*opt_xyz)[1] / (*opt_xyz)[2]; int const exponent = std::floor(std::log10(std::abs(expected_voxel))); this->expectedVoxelLabel->setText( @@ -139,10 +139,10 @@ void Vtu2GridDialog::accept() return; } - auto opt_xyz = fillXYZ(this->xlineEdit->text(), this->ylineEdit->text(), - this->zlineEdit->text()); + auto cellsize = fillXYZ(this->xlineEdit->text(), this->ylineEdit->text(), + this->zlineEdit->text()); - if (!opt_xyz) + if (!cellsize) { OGSError::box( "At least the x-length of a voxel must be specified and > 0.\n If " @@ -151,7 +151,6 @@ void Vtu2GridDialog::accept() "treated as " "the x-input."); } - auto const& cellsize = opt_xyz.value(); auto _mesh( _mesh_model.getMesh(this->meshListBox->currentText().toStdString())); @@ -179,17 +178,18 @@ void Vtu2GridDialog::accept() "The range (max-min of the bounding box) is not allowed to be < 0"); } std::array const dims = - VoxelGridFromMesh::getNumberOfVoxelPerDimension(ranges, cellsize); + VoxelGridFromMesh::getNumberOfVoxelPerDimension(ranges, *cellsize); std::unique_ptr grid( - generateRegularHexMesh(dims[0], dims[1], dims[2], cellsize[0], - cellsize[1], cellsize[2], min, "grid")); + generateRegularHexMesh(dims[0], dims[1], dims[2], (*cellsize)[0], + (*cellsize)[1], (*cellsize)[2], min, "grid")); if (grid == nullptr) { OGS_FATAL( "Could not generate regular hex mesh. With parameters dims={} {} " "{}, " "cellsize={} {} {}", - dims[0], dims[1], dims[2], cellsize[0], cellsize[1], cellsize[2]); + dims[0], dims[1], dims[2], (*cellsize)[0], (*cellsize)[1], + (*cellsize)[2]); } std::vector* cell_ids = @@ -199,7 +199,7 @@ void Vtu2GridDialog::accept() { OGS_FATAL("Could not create cell ids."); } - *cell_ids = VoxelGridFromMesh::assignCellIds(mesh, min, dims, cellsize); + *cell_ids = VoxelGridFromMesh::assignCellIds(mesh, min, dims, *cellsize); if (!VoxelGridFromMesh::removeUnusedGridCells(mesh, grid)) { return;