Files
create/src/Mod/Mesh/Gui/DlgSmoothing.cpp

241 lines
8.1 KiB
C++

/***************************************************************************
* Copyright (c) 2010 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QButtonGroup>
# include <QDialogButtonBox>
#endif
#include "DlgSmoothing.h"
#include "ui_DlgSmoothing.h"
#include "Selection.h"
#include <Gui/WaitCursor.h>
#include <Gui/Command.h>
#include <Gui/Selection.h>
#include <Mod/Mesh/App/MeshFeature.h>
#include <Mod/Mesh/App/Core/Smoothing.h>
using namespace MeshGui;
/* TRANSLATOR MeshGui::DlgSmoothing */
DlgSmoothing::DlgSmoothing(QWidget* parent)
: QWidget(parent), ui(new Ui_DlgSmoothing())
{
ui->setupUi(this);
bg = new QButtonGroup(this);
bg->addButton(ui->radioButtonTaubin, 0);
bg->addButton(ui->radioButtonLaplace, 1);
connect(bg, SIGNAL(buttonClicked(int)),
this, SLOT(method_clicked(int)));
ui->labelLambda->setText(QString::fromUtf8("\xce\xbb"));
ui->labelMu->setText(QString::fromUtf8("\xce\xbc"));
this->resize(this->sizeHint());
}
/*
* Destroys the object and frees any allocated resources
*/
DlgSmoothing::~DlgSmoothing()
{
// no need to delete child widgets, Qt does it all for us
delete ui;
}
void DlgSmoothing::method_clicked(int id)
{
if (bg->button(id) == ui->radioButtonTaubin) {
ui->labelMu->setEnabled(true);
ui->spinMicro->setEnabled(true);
}
else {
ui->labelMu->setEnabled(false);
ui->spinMicro->setEnabled(false);
}
}
int DlgSmoothing::iterations() const
{
return ui->iterations->value();
}
double DlgSmoothing::lambdaStep() const
{
return ui->spinLambda->value();
}
double DlgSmoothing::microStep() const
{
return ui->spinMicro->value();
}
DlgSmoothing::Smooth DlgSmoothing::method() const
{
if (ui->radioButtonTaubin->isChecked())
return DlgSmoothing::Taubin;
else if (ui->radioButtonLaplace->isChecked())
return DlgSmoothing::Laplace;
return DlgSmoothing::None;
}
bool DlgSmoothing::smoothSelection() const
{
return ui->checkBoxSelection->isChecked();
}
void DlgSmoothing::on_checkBoxSelection_toggled(bool on)
{
Q_EMIT toggledSelection(on);
}
// ------------------------------------------------
SmoothingDialog::SmoothingDialog(QWidget* parent, Qt::WindowFlags fl)
: QDialog(parent, fl)
{
widget = new DlgSmoothing(this);
this->setWindowTitle(widget->windowTitle());
QVBoxLayout* hboxLayout = new QVBoxLayout(this);
QDialogButtonBox* buttonBox = new QDialogButtonBox(this);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
connect(buttonBox, SIGNAL(accepted()),
this, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()),
this, SLOT(reject()));
hboxLayout->addWidget(widget);
hboxLayout->addWidget(buttonBox);
}
SmoothingDialog::~SmoothingDialog()
{
}
// ---------------------------------------
/* TRANSLATOR MeshGui::TaskSmoothing */
TaskSmoothing::TaskSmoothing()
{
widget = new DlgSmoothing();
Gui::TaskView::TaskBox* taskbox = new Gui::TaskView::TaskBox(
QPixmap(), widget->windowTitle(), false, nullptr);
taskbox->groupLayout()->addWidget(widget);
Content.push_back(taskbox);
selection = new Selection();
selection->setObjects(Gui::Selection().getSelectionEx(nullptr, Mesh::Feature::getClassTypeId()));
Gui::Selection().clearSelection();
Gui::TaskView::TaskBox* tasksel = new Gui::TaskView::TaskBox();
tasksel->groupLayout()->addWidget(selection);
tasksel->hide();
Content.push_back(tasksel);
connect(widget, SIGNAL(toggledSelection(bool)),
tasksel, SLOT(setVisible(bool)));
}
TaskSmoothing::~TaskSmoothing()
{
// automatically deleted in the sub-class
}
bool TaskSmoothing::accept()
{
std::vector<App::DocumentObject*> meshes = selection->getObjects();
if (meshes.empty())
return true;
Gui::WaitCursor wc;
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Mesh Smoothing"));
bool hasSelection = false;
for (std::vector<App::DocumentObject*>::const_iterator it = meshes.begin(); it != meshes.end(); ++it) {
Mesh::Feature* mesh = static_cast<Mesh::Feature*>(*it);
std::vector<Mesh::FacetIndex> selection;
if (widget->smoothSelection()) {
// clear the selection before editing the mesh to avoid
// to have coloured triangles when doing an 'undo'
const Mesh::MeshObject* mm = mesh->Mesh.getValuePtr();
mm->getFacetsFromSelection(selection);
selection = mm->getPointsFromFacets(selection);
mm->clearFacetSelection();
if (!selection.empty())
hasSelection = true;
}
Mesh::MeshObject* mm = mesh->Mesh.startEditing();
switch (widget->method()) {
case MeshGui::DlgSmoothing::Taubin:
{
MeshCore::TaubinSmoothing s(mm->getKernel());
s.SetLambda(widget->lambdaStep());
s.SetMicro(widget->microStep());
if (widget->smoothSelection()) {
s.SmoothPoints(widget->iterations(), selection);
}
else {
s.Smooth(widget->iterations());
}
} break;
case MeshGui::DlgSmoothing::Laplace:
{
MeshCore::LaplaceSmoothing s(mm->getKernel());
s.SetLambda(widget->lambdaStep());
if (widget->smoothSelection()) {
s.SmoothPoints(widget->iterations(), selection);
}
else {
s.Smooth(widget->iterations());
}
} break;
case MeshGui::DlgSmoothing::MedianFilter:
{
MeshCore::MedianFilterSmoothing s(mm->getKernel());
if (widget->smoothSelection()) {
s.SmoothPoints(widget->iterations(), selection);
}
else {
s.Smooth(widget->iterations());
}
} break;
default:
break;
}
mesh->Mesh.finishEditing();
}
if (widget->smoothSelection() && !hasSelection) {
Gui::Command::abortCommand();
return false;
}
Gui::Command::commitCommand();
return true;
}
#include "moc_DlgSmoothing.cpp"