Forked from
ogs / ogs
16009 commits behind the upstream repository.
-
Karsten Rink authoredKarsten Rink authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
MeshElementRemovalDialog.cpp 11.25 KiB
/**
* \file
* \author Karsten Rink
* \date 2013-10-16
* \brief Implementation of the MeshElementRemovalDialog class.
*
* \copyright
* Copyright (c) 2012-2018, 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 "MeshElementRemovalDialog.h"
#include <QList>
#include <QListWidgetItem>
#include <algorithm>
#include "Applications/DataExplorer/Base/OGSError.h"
#include "Applications/DataHolderLib/Project.h"
#include "Elements/Element.h"
#include "GeoLib/AABB.h"
#include "MeshLib/Mesh.h"
#include "MeshLib/MeshEditing/RemoveMeshComponents.h"
#include "MeshLib/MeshSearch/ElementSearch.h"
#include "MeshLib/Node.h"
#include "MeshLib/Properties.h"
#include "MeshLib/PropertyVector.h"
/// Constructor
MeshElementRemovalDialog::MeshElementRemovalDialog(
DataHolderLib::Project const& project, QDialog* parent)
: QDialog(parent),
_project(project),
_currentIndex(0),
_aabbIndex(std::numeric_limits<unsigned>::max()),
_scalarIndex(std::numeric_limits<unsigned>::max())
{
setupUi(this);
auto const& mesh_vec(_project.getMeshObjects());
const std::size_t nMeshes (mesh_vec.size());
for (std::size_t i=0; i<nMeshes; ++i)
{
std::string name = mesh_vec[i]->getName();
this->meshNameComboBox->addItem(QString::fromStdString(name));
}
if (mesh_vec.empty())
{
OGSError::box("No meshes available.");
QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection);
}
}
MeshElementRemovalDialog::~MeshElementRemovalDialog() = default;
void MeshElementRemovalDialog::accept()
{
if (this->newMeshNameEdit->text().size()==0)
{
OGSError::box("Please enter name for new mesh.");
return;
}
bool anything_checked (false);
const MeshLib::Mesh* msh = _project.getMesh(this->meshNameComboBox->currentText().toStdString());
MeshLib::ElementSearch ex(*msh);
if (this->elementTypeCheckBox->isChecked())
{
QList<QListWidgetItem*> items = this->elementTypeListWidget->selectedItems();
for (auto& item : items)
ex.searchByElementType(
MeshLib::String2MeshElemType(item->text().toStdString()));
anything_checked = true;
}
if (this->scalarArrayCheckBox->isChecked())
{
std::string const array_name = this->scalarArrayComboBox->currentText().toStdString();
double min_val, max_val;
bool outside = this->outsideButton->isChecked();
if (outside)
{
min_val = this->outsideScalarMinEdit->text().toDouble();
max_val = this->outsideScalarMaxEdit->text().toDouble();
}
else
{
min_val = this->insideScalarMinEdit->text().toDouble();
max_val = this->insideScalarMaxEdit->text().toDouble();
}
ex.searchByPropertyValueRange(array_name, min_val, max_val, outside);
anything_checked = true;
}
if (this->boundingBoxCheckBox->isChecked())
{
std::vector<MeshLib::Node*> const& nodes (_project.getMesh(this->meshNameComboBox->currentText().toStdString())->getNodes());
GeoLib::AABB const aabb(nodes.begin(), nodes.end());
auto minAABB = aabb.getMinPoint();
auto maxAABB = aabb.getMaxPoint();
// only extract bounding box parameters that have been edited (otherwise there will be rounding errors!)
minAABB[0] = (aabb_edits[0]) ? this->xMinEdit->text().toDouble() : (minAABB[0]);
maxAABB[0] = (aabb_edits[1]) ? this->xMaxEdit->text().toDouble() : (maxAABB[0]);
minAABB[1] = (aabb_edits[2]) ? this->yMinEdit->text().toDouble() : (minAABB[1]);
maxAABB[1] = (aabb_edits[3]) ? this->yMaxEdit->text().toDouble() : (maxAABB[1]);
minAABB[2] = (aabb_edits[4]) ? this->zMinEdit->text().toDouble() : (minAABB[2]);
maxAABB[2] = (aabb_edits[5]) ? this->zMaxEdit->text().toDouble() : (maxAABB[2]);
std::vector<MathLib::Point3d> extent;
extent.push_back(minAABB);
extent.push_back(maxAABB);
const GeoLib::AABB updated_aabb(extent.begin(), extent.end());
ex.searchByBoundingBox(updated_aabb);
anything_checked = true;
}
if (this->zeroVolumeCheckBox->isChecked())
{
ex.searchByContent();
anything_checked = true;
}
if (anything_checked)
{
MeshLib::Mesh* new_mesh = MeshLib::removeElements(*msh, ex.getSearchedElementIDs(), this->newMeshNameEdit->text().toStdString());
if (new_mesh)
emit meshAdded(new_mesh);
else
{
if (new_mesh == nullptr)
OGSError::box("The current selection removes ALL mesh elements.\nPlease change the selection.");
if (ex.getSearchedElementIDs().empty())
OGSError::box("The current selection removes NO mesh elements.");
delete new_mesh;
return;
}
}
else
{
OGSError::box("No condition set for elements to remove.");
return;
}
this->done(QDialog::Accepted);
}
void MeshElementRemovalDialog::reject()
{
this->done(QDialog::Rejected);
}
std::size_t MeshElementRemovalDialog::addScalarArrays(MeshLib::Mesh const& mesh) const
{
MeshLib::Properties const& properties = mesh.getProperties();
std::vector<std::string> const& names = properties.getPropertyVectorNames();
for (auto name : names)
{
if (properties.existsPropertyVector<int>(name))
{
auto const p = properties.getPropertyVector<int>(name);
if (p->getMeshItemType() == MeshLib::MeshItemType::Cell)
{
this->scalarArrayComboBox->addItem(QString::fromStdString(name));
enableScalarArrayWidgets(true);
}
}
if (properties.existsPropertyVector<double>(name))
{
auto const p = properties.getPropertyVector<double>(name);
if (p->getMeshItemType() == MeshLib::MeshItemType::Cell)
{
this->scalarArrayComboBox->addItem(QString::fromStdString(name));
enableScalarArrayWidgets(true);
}
}
}
return this->scalarArrayComboBox->count();
}
void MeshElementRemovalDialog::enableScalarArrayWidgets(bool enable) const
{
this->scalarArrayComboBox->setEnabled(enable);
this->outsideButton->setEnabled(enable);
this->insideButton->setEnabled(enable);
this->outsideScalarMinEdit->setEnabled(enable && this->outsideButton->isChecked());
this->outsideScalarMaxEdit->setEnabled(enable && this->outsideButton->isChecked());
this->insideScalarMinEdit->setEnabled(enable && this->insideButton->isChecked());
this->insideScalarMaxEdit->setEnabled(enable && this->insideButton->isChecked());
}
void MeshElementRemovalDialog::toggleScalarEdits(bool outside) const
{
this->outsideScalarMinEdit->setEnabled(outside);
this->outsideScalarMaxEdit->setEnabled(outside);
this->insideScalarMinEdit->setEnabled(!outside);
this->insideScalarMaxEdit->setEnabled(!outside);
}
void MeshElementRemovalDialog::on_insideButton_toggled(bool is_checked)
{
if (this->insideButton->isChecked())
toggleScalarEdits(false);
else
toggleScalarEdits(true);
}
void MeshElementRemovalDialog::on_boundingBoxCheckBox_toggled(bool is_checked)
{
this->xMinEdit->setEnabled(is_checked); this->xMaxEdit->setEnabled(is_checked);
this->yMinEdit->setEnabled(is_checked); this->yMaxEdit->setEnabled(is_checked);
this->zMinEdit->setEnabled(is_checked); this->zMaxEdit->setEnabled(is_checked);
if (is_checked && (_currentIndex != _aabbIndex))
{
_aabbIndex = _currentIndex;
std::vector<MeshLib::Node*> const& nodes (_project.getMesh(this->meshNameComboBox->currentText().toStdString())->getNodes());
GeoLib::AABB aabb(nodes.begin(), nodes.end());
auto const& minAABB = aabb.getMinPoint();
auto const& maxAABB = aabb.getMaxPoint();
this->xMinEdit->setText(QString::number(minAABB[0], 'f'));
this->xMaxEdit->setText(QString::number(maxAABB[0], 'f'));
this->yMinEdit->setText(QString::number(minAABB[1], 'f'));
this->yMaxEdit->setText(QString::number(maxAABB[1], 'f'));
this->zMinEdit->setText(QString::number(minAABB[2], 'f'));
this->zMaxEdit->setText(QString::number(maxAABB[2], 'f'));
aabb_edits.fill(false);
}
}
void MeshElementRemovalDialog::on_elementTypeCheckBox_toggled(bool is_checked)
{
this->elementTypeListWidget->setEnabled(is_checked);
}
void MeshElementRemovalDialog::on_scalarArrayCheckBox_toggled(bool is_checked)
{
if (!is_checked)
{
enableScalarArrayWidgets(false);
return;
}
MeshLib::Mesh const* const mesh =
_project.getMesh(meshNameComboBox->currentText().toStdString());
if (addScalarArrays(*mesh) > 0)
enableScalarArrayWidgets(true);
else
{
enableScalarArrayWidgets(false);
OGSError::box("No scalar arrays found");
on_scalarArrayCheckBox_toggled(false);
}
}
void MeshElementRemovalDialog::on_meshNameComboBox_currentIndexChanged(int idx)
{
Q_UNUSED(idx);
this->_currentIndex = this->meshNameComboBox->currentIndex();
this->newMeshNameEdit->setText(this->meshNameComboBox->currentText() + "_new");
this->elementTypeListWidget->clearSelection();
this->scalarArrayComboBox->clear();
this->outsideScalarMinEdit->setText("");
this->outsideScalarMaxEdit->setText("");
this->insideScalarMinEdit->setText("");
this->insideScalarMaxEdit->setText("");
if (this->scalarArrayCheckBox->isChecked())
on_scalarArrayCheckBox_toggled(true);
if (this->boundingBoxCheckBox->isChecked())
on_boundingBoxCheckBox_toggled(true);
}
void MeshElementRemovalDialog::on_scalarArrayComboBox_currentIndexChanged(int idx)
{
Q_UNUSED(idx);
MeshLib::Mesh const* const mesh =
_project.getMesh(meshNameComboBox->currentText().toStdString());
MeshLib::Properties const& properties = mesh->getProperties();
std::string const vec_name(scalarArrayComboBox->currentText().toStdString());
if (vec_name == "")
return;
if (properties.existsPropertyVector<int>(vec_name))
{
MeshLib::PropertyVector<int> const& vec =
*properties.getPropertyVector<int>(vec_name);
auto min = std::min_element(vec.cbegin(), vec.cend());
auto max = std::max_element(vec.cbegin(), vec.cend());
this->outsideScalarMinEdit->setText(QString::number(*min));
this->outsideScalarMaxEdit->setText(QString::number(*max));
this->insideScalarMinEdit->setText(QString::number(*min));
this->insideScalarMaxEdit->setText(QString::number(*max));
}
else if (properties.existsPropertyVector<double>(vec_name))
{
MeshLib::PropertyVector<double> const& vec =
*properties.getPropertyVector<double>(vec_name);
auto min = std::min_element(vec.cbegin(), vec.cend());
auto max = std::max_element(vec.cbegin(), vec.cend());
this->outsideScalarMinEdit->setText(QString::number(*min));
this->outsideScalarMaxEdit->setText(QString::number(*max));
this->insideScalarMinEdit->setText(QString::number(*min));
this->insideScalarMaxEdit->setText(QString::number(*max));
}
}