OGS
MeshElementRemovalDialog.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
5
6#include <Eigen/StdVector>
7#include <QList>
8#include <QListWidgetItem>
9#include <algorithm>
10
13#include "GeoLib/AABB.h"
15#include "MeshLib/Mesh.h"
17#include "MeshLib/Node.h"
18#include "MeshLib/Properties.h"
20
23 DataHolderLib::Project const& project, QDialog* parent)
24 : QDialog(parent),
25 _project(project),
27 _aabbIndex(std::numeric_limits<unsigned>::max()),
28 _scalarIndex(std::numeric_limits<unsigned>::max())
29{
30 setupUi(this);
31
32 auto const& mesh_vec(_project.getMeshObjects());
33
34 const std::size_t nMeshes(mesh_vec.size());
35 for (std::size_t i = 0; i < nMeshes; ++i)
36 {
37 std::string name = mesh_vec[i]->getName();
38 this->meshNameComboBox->addItem(QString::fromStdString(name));
39 }
40
41 if (mesh_vec.empty())
42 {
43 OGSError::box("No meshes available.");
44 QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection);
45 }
46}
47
49
51{
52 if (this->newMeshNameEdit->text().size() == 0)
53 {
54 OGSError::box("Please enter name for new mesh.");
55 return;
56 }
57
58 bool anything_checked(false);
59
60 const MeshLib::Mesh* msh =
61 _project.getMesh(this->meshNameComboBox->currentText().toStdString());
63 if (this->elementTypeCheckBox->isChecked())
64 {
65 QList<QListWidgetItem*> items =
66 this->elementTypeListWidget->selectedItems();
67 for (auto& item : items)
68 {
70 MeshLib::String2MeshElemType(item->text().toStdString()));
71 }
72 anything_checked = true;
73 }
74 if (this->scalarArrayCheckBox->isChecked())
75 {
76 std::string const array_name =
77 this->scalarArrayComboBox->currentText().toStdString();
78 double min_val;
79 double max_val;
80 bool outside = this->outsideButton->isChecked();
81 if (outside)
82 {
83 min_val = this->outsideScalarMinEdit->text().toDouble();
84 max_val = this->outsideScalarMaxEdit->text().toDouble();
85 }
86 else
87 {
88 min_val = this->insideScalarMinEdit->text().toDouble();
89 max_val = this->insideScalarMaxEdit->text().toDouble();
90 }
91
92 std::size_t n_marked_elements(0);
93 if (msh->getProperties().existsPropertyVector<double>(array_name))
94 {
95 n_marked_elements = ex.searchByPropertyValueRange<double>(
96 array_name, min_val, max_val, outside);
97 }
98 if (msh->getProperties().existsPropertyVector<int>(array_name))
99 {
100 int const lbound = static_cast<int>(min_val);
101 int const rbound = static_cast<int>(max_val);
102 n_marked_elements = ex.searchByPropertyValueRange<int>(
103 array_name, lbound, rbound, outside);
104 }
105
106 if (n_marked_elements > 0)
107 {
108 anything_checked = true;
109 }
110 }
111 if (this->boundingBoxCheckBox->isChecked())
112 {
113 std::vector<MeshLib::Node*> const& nodes(
115 .getMesh(this->meshNameComboBox->currentText().toStdString())
116 ->getNodes());
117 GeoLib::AABB const aabb(nodes.begin(), nodes.end());
118 auto [minAABB, maxAABB] = aabb.getMinMaxPoints();
119
120 // only extract bounding box parameters that have been edited (otherwise
121 // there will be rounding errors!)
122 minAABB[0] =
123 (aabb_edits[0]) ? this->xMinEdit->text().toDouble() : (minAABB[0]);
124 maxAABB[0] =
125 (aabb_edits[1]) ? this->xMaxEdit->text().toDouble() : (maxAABB[0]);
126 minAABB[1] =
127 (aabb_edits[2]) ? this->yMinEdit->text().toDouble() : (minAABB[1]);
128 maxAABB[1] =
129 (aabb_edits[3]) ? this->yMaxEdit->text().toDouble() : (maxAABB[1]);
130 minAABB[2] =
131 (aabb_edits[4]) ? this->zMinEdit->text().toDouble() : (minAABB[2]);
132 maxAABB[2] =
133 (aabb_edits[5]) ? this->zMaxEdit->text().toDouble() : (maxAABB[2]);
134 std::vector<Eigen::Vector3d, Eigen::aligned_allocator<Eigen::Vector3d>>
135 extent{minAABB, maxAABB};
136 const GeoLib::AABB updated_aabb(extent.begin(), extent.end());
137 ex.searchByBoundingBox(updated_aabb,
138 this->invertBoundingBoxCheckBox->isChecked());
139 anything_checked = true;
140 }
141
142 if (this->zeroVolumeCheckBox->isChecked())
143 {
144 ex.searchByContent();
145 anything_checked = true;
146 }
147
148 if (anything_checked)
149 {
151 *msh, ex.getSearchedElementIDs(),
152 this->newMeshNameEdit->text().toStdString());
153 if (new_mesh)
154 {
155 emit meshAdded(new_mesh);
156 }
157 else
158 {
159 if (ex.getSearchedElementIDs().empty())
160 {
162 "The current selection removes NO mesh elements.");
163 }
164 return;
165 }
166 }
167 else
168 {
169 OGSError::box("No condition set for elements to remove.");
170 return;
171 }
172
173 this->done(QDialog::Accepted);
174}
175
177{
178 this->done(QDialog::Rejected);
179}
180
182 MeshLib::Mesh const& mesh) const
183{
184 for (auto [name, property] : mesh.getProperties())
185 {
186 if (property->getMeshItemType() != MeshLib::MeshItemType::Cell)
187 {
188 continue;
189 }
190 this->scalarArrayComboBox->addItem(
191 QString::fromStdString(std::string(name)));
193 }
194 return this->scalarArrayComboBox->count();
195}
196
198{
199 this->scalarArrayComboBox->setEnabled(enable);
200 this->outsideButton->setEnabled(enable);
201 this->insideButton->setEnabled(enable);
202 this->outsideScalarMinEdit->setEnabled(enable &&
203 this->outsideButton->isChecked());
204 this->outsideScalarMaxEdit->setEnabled(enable &&
205 this->outsideButton->isChecked());
206 this->insideScalarMinEdit->setEnabled(enable &&
207 this->insideButton->isChecked());
208 this->insideScalarMaxEdit->setEnabled(enable &&
209 this->insideButton->isChecked());
210}
211
213{
214 this->outsideScalarMinEdit->setEnabled(outside);
215 this->outsideScalarMaxEdit->setEnabled(outside);
216 this->insideScalarMinEdit->setEnabled(!outside);
217 this->insideScalarMaxEdit->setEnabled(!outside);
218}
219
221{
222 toggleScalarEdits(!this->insideButton->isChecked());
223}
224
226{
227 this->invertBoundingBoxCheckBox->setEnabled(is_checked);
228 this->xMinEdit->setEnabled(is_checked);
229 this->xMaxEdit->setEnabled(is_checked);
230 this->yMinEdit->setEnabled(is_checked);
231 this->yMaxEdit->setEnabled(is_checked);
232 this->zMinEdit->setEnabled(is_checked);
233 this->zMaxEdit->setEnabled(is_checked);
234
235 if (is_checked && (_currentIndex != _aabbIndex))
236 {
238 std::vector<MeshLib::Node*> const& nodes(
240 .getMesh(this->meshNameComboBox->currentText().toStdString())
241 ->getNodes());
242 GeoLib::AABB aabb(nodes.begin(), nodes.end());
243 auto const& minAABB = aabb.getMinPoint();
244 auto const& maxAABB = aabb.getMaxPoint();
245 this->xMinEdit->setText(QString::number(minAABB[0], 'f'));
246 this->xMaxEdit->setText(QString::number(maxAABB[0], 'f'));
247 this->yMinEdit->setText(QString::number(minAABB[1], 'f'));
248 this->yMaxEdit->setText(QString::number(maxAABB[1], 'f'));
249 this->zMinEdit->setText(QString::number(minAABB[2], 'f'));
250 this->zMaxEdit->setText(QString::number(maxAABB[2], 'f'));
251 aabb_edits.fill(false);
252 }
253}
254
256 bool const is_checked)
257{
258 if (is_checked == true)
259 {
260 this->xOutsideLabel->setText("X between");
261 this->yOutsideLabel->setText("Y between");
262 this->zOutsideLabel->setText("Z between");
263 }
264 else
265 {
266 this->xOutsideLabel->setText("X outside of");
267 this->yOutsideLabel->setText("Y outside of");
268 this->zOutsideLabel->setText("Z outside of");
269 }
270}
271
273{
274 this->elementTypeListWidget->setEnabled(is_checked);
275}
276
278{
279 if (!is_checked)
280 {
282 return;
283 }
284
285 MeshLib::Mesh const* const mesh =
286 _project.getMesh(meshNameComboBox->currentText().toStdString());
287 if (addScalarArrays(*mesh) > 0)
288 {
290 }
291 else
292 {
294 OGSError::box("No scalar arrays found");
296 }
297}
298
300{
301 Q_UNUSED(idx);
302 this->_currentIndex = this->meshNameComboBox->currentIndex();
303 this->newMeshNameEdit->setText(this->meshNameComboBox->currentText() +
304 "_new");
305 this->elementTypeListWidget->clearSelection();
306 this->scalarArrayComboBox->clear();
307 this->outsideScalarMinEdit->setText("");
308 this->outsideScalarMaxEdit->setText("");
309 this->insideScalarMinEdit->setText("");
310 this->insideScalarMaxEdit->setText("");
311 on_scalarArrayCheckBox_toggled(this->scalarArrayCheckBox->isChecked());
312 on_boundingBoxCheckBox_toggled(this->boundingBoxCheckBox->isChecked());
313}
314
316 int idx)
317{
318 Q_UNUSED(idx);
319 std::string const vec_name(
320 scalarArrayComboBox->currentText().toStdString());
321 if (vec_name.empty())
322 {
323 return;
324 }
325
326 MeshLib::Mesh const* const mesh =
327 _project.getMesh(meshNameComboBox->currentText().toStdString());
328 if (mesh == nullptr)
329 {
330 return;
331 }
332 MeshLib::Properties const& properties = mesh->getProperties();
333
334 if (properties.existsPropertyVector<int>(vec_name))
335 {
336 setRangeValues<int>(*properties.getPropertyVector<int>(vec_name));
337 }
338 else if (properties.existsPropertyVector<double>(vec_name))
339 {
340 setRangeValues<double>(*properties.getPropertyVector<double>(vec_name));
341 }
342}
343
344template <typename T>
347{
348 auto min = std::min_element(vec.cbegin(), vec.cend());
349 auto max = std::max_element(vec.cbegin(), vec.cend());
350 this->outsideScalarMinEdit->setText(QString::number(*min));
351 this->outsideScalarMaxEdit->setText(QString::number(*max));
352 this->insideScalarMinEdit->setText(QString::number(*min));
353 this->insideScalarMaxEdit->setText(QString::number(*max));
354}
Class AABB is an axis aligned bounding box around a given set of geometric points of (template) type ...
Definition AABB.h:45
Eigen::Vector3d const & getMaxPoint() const
Definition AABB.h:176
Eigen::Vector3d const & getMinPoint() const
Definition AABB.h:169
MinMaxPoints getMinMaxPoints() const
Definition AABB.h:163
~MeshElementRemovalDialog() override
void setRangeValues(MeshLib::PropertyVector< T > const &vec)
void on_elementTypeCheckBox_toggled(bool is_checked)
MeshElementRemovalDialog(DataHolderLib::Project const &project, QDialog *parent=nullptr)
Constructor.
void toggleScalarEdits(bool outside) const
DataHolderLib::Project const & _project
void on_insideButton_toggled(bool is_checked)
void on_invertBoundingBoxCheckBox_toggled(bool const is_checked)
void meshAdded(MeshLib::Mesh *mesh)
void on_scalarArrayCheckBox_toggled(bool is_checked)
void on_scalarArrayComboBox_currentIndexChanged(int idx)
std::size_t addScalarArrays(MeshLib::Mesh const &mesh) const
void enableScalarArrayWidgets(bool enable) const
void on_boundingBoxCheckBox_toggled(bool is_checked)
Element search class.
std::size_t searchByBoundingBox(GeoLib::AABB const &aabb, bool const invert=false)
const std::vector< std::size_t > & getSearchedElementIDs() const
return marked elements
std::size_t searchByElementType(MeshElemType eleType)
Marks all elements of the given element type.
std::size_t searchByPropertyValueRange(std::string const &property_name, PROPERTY_TYPE const min_property_value, PROPERTY_TYPE const max_property_value, bool outside_of)
std::size_t searchByContent(double eps=std::numeric_limits< double >::epsilon())
Marks all elements with a volume smaller than eps.
Properties & getProperties()
Definition Mesh.h:125
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
bool existsPropertyVector(std::string_view name) const
PropertyVector< T > const * getPropertyVector(std::string_view name) const
constexpr const PROP_VAL_TYPE * cbegin() const
constexpr const PROP_VAL_TYPE * cend() const
static void box(const QString &e)
Definition OGSError.cpp:13
MeshElemType String2MeshElemType(const std::string &s)
Given a string of the shortened name of the element type, this returns the corresponding MeshElemType...
Definition MeshEnums.cpp:84
MeshLib::Mesh * removeElements(const MeshLib::Mesh &mesh, const std::vector< std::size_t > &removed_element_ids, const std::string &new_mesh_name)