1
/***************************************************************************
2
* Copyright (c) 2006 Werner Mayer <wmayer[at]users.sourceforge.net> *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
23
#include "PreCompiled.h"
31
#include <Gui/Application.h>
32
#include <Gui/Command.h>
33
#include <Gui/Document.h>
34
#include <Gui/DockWindowManager.h>
35
#include <Gui/MainWindow.h>
36
#include <Gui/WaitCursor.h>
37
#include <Gui/View3DInventor.h>
38
#include <Gui/View3DInventorViewer.h>
39
#include <Mod/Mesh/App/MeshFeature.h>
40
#include <Mod/Mesh/App/Core/Evaluation.h>
41
#include <Mod/Mesh/App/Core/Degeneration.h>
43
#include "DlgEvaluateMeshImp.h"
44
#include "ui_DlgEvaluateMesh.h"
45
#include "DlgEvaluateSettings.h"
46
#include "ViewProviderDefects.h"
49
using namespace MeshCore;
51
using namespace MeshGui;
53
CleanupHandler::CleanupHandler()
56
// connect to lstWindowClosed signal
57
connect(qApp, &QApplication::lastWindowClosed, this, &CleanupHandler::cleanup);
60
// The lastWindowClosed signal will be emitted recursively and before the cleanup slot is finished
61
// therefore all code inside this function must handle this case!
62
void CleanupHandler::cleanup()
64
DockEvaluateMeshImp::destruct();
67
// -------------------------------------------------------------
69
class DlgEvaluateMeshImp::Private
76
void showFoldsFunction(bool on)
78
ui.label_9->setVisible(on);
79
ui.line_9->setVisible(on);
80
ui.checkFoldsButton->setVisible(on);
81
ui.analyzeFoldsButton->setVisible(on);
82
ui.repairFoldsButton->setVisible(on);
85
Ui_DlgEvaluateMesh ui {};
86
std::map<std::string, ViewProviderMeshDefects*> vp;
87
Mesh::Feature* meshFeature {nullptr};
88
QPointer<Gui::View3DInventor> view;
89
std::vector<Mesh::FacetIndex> self_intersections;
90
bool enableFoldsCheck {false};
91
bool checkNonManfoldPoints {false};
92
bool strictlyDegenerated {true};
93
float epsilonDegenerated {0.0F};
96
/* TRANSLATOR MeshGui::DlgEvaluateMeshImp */
99
* Constructs a DlgEvaluateMeshImp which is a child of 'parent', with the
100
* widget flags set to 'f'.
102
DlgEvaluateMeshImp::DlgEvaluateMeshImp(QWidget* parent, Qt::WindowFlags fl)
103
: QDialog(parent, fl)
109
d->ui.line->setFrameShape(QFrame::HLine);
110
d->ui.line->setFrameShadow(QFrame::Sunken);
111
d->ui.line_2->setFrameShape(QFrame::HLine);
112
d->ui.line_2->setFrameShadow(QFrame::Sunken);
113
d->ui.line_3->setFrameShape(QFrame::HLine);
114
d->ui.line_3->setFrameShadow(QFrame::Sunken);
115
d->ui.line_4->setFrameShape(QFrame::HLine);
116
d->ui.line_4->setFrameShadow(QFrame::Sunken);
117
d->ui.line_5->setFrameShape(QFrame::HLine);
118
d->ui.line_5->setFrameShadow(QFrame::Sunken);
119
d->ui.line_6->setFrameShape(QFrame::HLine);
120
d->ui.line_6->setFrameShadow(QFrame::Sunken);
121
d->ui.line_7->setFrameShape(QFrame::HLine);
122
d->ui.line_7->setFrameShadow(QFrame::Sunken);
123
d->ui.line_8->setFrameShape(QFrame::HLine);
124
d->ui.line_8->setFrameShadow(QFrame::Sunken);
126
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
127
"User parameter:BaseApp/Preferences/Mod/Mesh/Evaluation");
128
d->checkNonManfoldPoints = hGrp->GetBool("CheckNonManifoldPoints", false);
129
d->enableFoldsCheck = hGrp->GetBool("EnableFoldsCheck", false);
130
d->strictlyDegenerated = hGrp->GetBool("StrictlyDegenerated", true);
131
if (d->strictlyDegenerated) {
132
d->epsilonDegenerated = 0.0F;
135
d->epsilonDegenerated = MeshCore::MeshDefinitions::_fMinPointDistanceP2;
138
d->showFoldsFunction(d->enableFoldsCheck);
140
QPushButton* button = d->ui.buttonBox->button(QDialogButtonBox::Open);
141
button->setText(tr("Settings..."));
143
// try to attach to the active document
144
this->onRefreshButtonClicked();
148
* Destroys the object and frees any allocated resources
150
DlgEvaluateMeshImp::~DlgEvaluateMeshImp()
152
// no need to delete child widgets, Qt does it all for us
153
for (const auto& it : d->vp) {
155
d->view->getViewer()->removeViewProvider(it.second);
161
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
162
"User parameter:BaseApp/Preferences/Mod/Mesh/Evaluation");
163
hGrp->SetBool("CheckNonManifoldPoints", d->checkNonManfoldPoints);
164
hGrp->SetBool("EnableFoldsCheck", d->enableFoldsCheck);
165
hGrp->SetBool("StrictlyDegenerated", d->strictlyDegenerated);
174
void DlgEvaluateMeshImp::setupConnections()
177
connect(d->ui.checkOrientationButton, &QCheckBox::clicked,
178
this, &DlgEvaluateMeshImp::onCheckOrientationButtonClicked);
179
connect(d->ui.analyzeOrientationButton, &QPushButton::clicked,
180
this, &DlgEvaluateMeshImp::onAnalyzeOrientationButtonClicked);
181
connect(d->ui.repairOrientationButton, &QPushButton::clicked,
182
this, &DlgEvaluateMeshImp::onRepairOrientationButtonClicked);
184
connect(d->ui.checkDuplicatedFacesButton, &QCheckBox::clicked,
185
this, &DlgEvaluateMeshImp::onCheckDuplicatedFacesButtonClicked);
186
connect(d->ui.analyzeDuplicatedFacesButton, &QPushButton::clicked,
187
this, &DlgEvaluateMeshImp::onAnalyzeDuplicatedFacesButtonClicked);
188
connect(d->ui.repairDuplicatedFacesButton, &QPushButton::clicked,
189
this, &DlgEvaluateMeshImp::onRepairDuplicatedFacesButtonClicked);
191
connect(d->ui.checkDuplicatedPointsButton, &QCheckBox::clicked,
192
this, &DlgEvaluateMeshImp::onCheckDuplicatedPointsButtonClicked);
193
connect(d->ui.analyzeDuplicatedPointsButton, &QPushButton::clicked,
194
this, &DlgEvaluateMeshImp::onAnalyzeDuplicatedPointsButtonClicked);
195
connect(d->ui.repairDuplicatedPointsButton, &QPushButton::clicked,
196
this, &DlgEvaluateMeshImp::onRepairDuplicatedPointsButtonClicked);
198
connect(d->ui.checkNonmanifoldsButton, &QCheckBox::clicked,
199
this, &DlgEvaluateMeshImp::onCheckNonmanifoldsButtonClicked);
200
connect(d->ui.analyzeNonmanifoldsButton, &QPushButton::clicked,
201
this, &DlgEvaluateMeshImp::onAnalyzeNonmanifoldsButtonClicked);
202
connect(d->ui.repairNonmanifoldsButton, &QPushButton::clicked,
203
this, &DlgEvaluateMeshImp::onRepairNonmanifoldsButtonClicked);
205
connect(d->ui.checkDegenerationButton, &QCheckBox::clicked,
206
this, &DlgEvaluateMeshImp::onCheckDegenerationButtonClicked);
207
connect(d->ui.analyzeDegeneratedButton, &QPushButton::clicked,
208
this, &DlgEvaluateMeshImp::onAnalyzeDegeneratedButtonClicked);
209
connect(d->ui.repairDegeneratedButton, &QPushButton::clicked,
210
this, &DlgEvaluateMeshImp::onRepairDegeneratedButtonClicked);
212
connect(d->ui.checkIndicesButton, &QCheckBox::clicked,
213
this, &DlgEvaluateMeshImp::onCheckIndicesButtonClicked);
214
connect(d->ui.analyzeIndicesButton, &QPushButton::clicked,
215
this, &DlgEvaluateMeshImp::onAnalyzeIndicesButtonClicked);
216
connect(d->ui.repairIndicesButton, &QPushButton::clicked,
217
this, &DlgEvaluateMeshImp::onRepairIndicesButtonClicked);
219
connect(d->ui.checkSelfIntersectionButton, &QCheckBox::clicked,
220
this, &DlgEvaluateMeshImp::onCheckSelfIntersectionButtonClicked);
221
connect(d->ui.analyzeSelfIntersectionButton, &QPushButton::clicked,
222
this, &DlgEvaluateMeshImp::onAnalyzeSelfIntersectionButtonClicked);
223
connect(d->ui.repairSelfIntersectionButton, &QPushButton::clicked,
224
this, &DlgEvaluateMeshImp::onRepairSelfIntersectionButtonClicked);
226
connect(d->ui.checkFoldsButton, &QCheckBox::clicked,
227
this, &DlgEvaluateMeshImp::onCheckFoldsButtonClicked);
228
connect(d->ui.analyzeFoldsButton, &QPushButton::clicked,
229
this, &DlgEvaluateMeshImp::onAnalyzeFoldsButtonClicked);
230
connect(d->ui.repairFoldsButton, &QPushButton::clicked,
231
this, &DlgEvaluateMeshImp::onRepairFoldsButtonClicked);
233
connect(d->ui.analyzeAllTogether, &QPushButton::clicked,
234
this, &DlgEvaluateMeshImp::onAnalyzeAllTogetherClicked);
235
connect(d->ui.repairAllTogether, &QPushButton::clicked,
236
this, &DlgEvaluateMeshImp::onRepairAllTogetherClicked);
238
connect(d->ui.refreshButton, &QPushButton::clicked,
239
this, &DlgEvaluateMeshImp::onRefreshButtonClicked);
240
connect(d->ui.meshNameButton, qOverload<int>(&QComboBox::activated),
241
this, &DlgEvaluateMeshImp::onMeshNameButtonActivated);
242
connect(d->ui.buttonBox, &QDialogButtonBox::clicked,
243
this, &DlgEvaluateMeshImp::onButtonBoxClicked);
244
connect(d->ui.buttonBox, &QDialogButtonBox::helpRequested,
245
Gui::getMainWindow(), &Gui::MainWindow::whatsThis);
249
void DlgEvaluateMeshImp::changeEvent(QEvent* e)
251
if (e->type() == QEvent::LanguageChange) {
252
d->ui.retranslateUi(this);
253
d->ui.meshNameButton->setItemText(0, tr("No selection"));
255
QDialog::changeEvent(e);
258
void DlgEvaluateMeshImp::slotCreatedObject(const App::DocumentObject& Obj)
260
// add new mesh object to the list
261
if (Obj.isDerivedFrom<Mesh::Feature>()) {
262
QString label = QString::fromUtf8(Obj.Label.getValue());
263
QString name = QString::fromLatin1(Obj.getNameInDocument());
264
d->ui.meshNameButton->addItem(label, name);
268
void DlgEvaluateMeshImp::slotDeletedObject(const App::DocumentObject& Obj)
270
// remove mesh objects from the list
271
if (Obj.isDerivedFrom<Mesh::Feature>()) {
272
int index = d->ui.meshNameButton->findData(QString::fromLatin1(Obj.getNameInDocument()));
274
d->ui.meshNameButton->removeItem(index);
275
d->ui.meshNameButton->setDisabled(d->ui.meshNameButton->count() < 2);
279
// is it the current mesh object then clear everything
280
if (&Obj == d->meshFeature) {
281
removeViewProviders();
282
d->meshFeature = nullptr;
283
d->ui.meshNameButton->setCurrentIndex(0);
285
d->self_intersections.clear();
289
void DlgEvaluateMeshImp::slotChangedObject(const App::DocumentObject& Obj,
290
const App::Property& Prop)
292
// if the current mesh object was modified update everything
293
if (&Obj == d->meshFeature && Prop.is<Mesh::PropertyMeshKernel>()) {
294
removeViewProviders();
297
d->self_intersections.clear();
299
else if (Obj.isDerivedFrom<Mesh::Feature>()) {
300
// if the label has changed update the entry in the list
301
if (Prop.is<App::PropertyString>() && strcmp(Prop.getName(), "Label") == 0) {
302
QString label = QString::fromUtf8(Obj.Label.getValue());
303
QString name = QString::fromLatin1(Obj.getNameInDocument());
304
int index = d->ui.meshNameButton->findData(name);
305
d->ui.meshNameButton->setItemText(index, label);
310
void DlgEvaluateMeshImp::slotDeletedDocument(const App::Document& Doc)
312
if (&Doc == getDocument()) {
313
// the view is already destroyed
314
for (const auto& it : d->vp) {
320
// try to attach to the active document
321
this->detachDocument();
323
onRefreshButtonClicked();
327
void DlgEvaluateMeshImp::setMesh(Mesh::Feature* m)
329
App::Document* doc = m->getDocument();
330
if (doc != getDocument()) {
336
int ct = d->ui.meshNameButton->count();
337
QString objName = QString::fromLatin1(m->getNameInDocument());
338
for (int i = 1; i < ct; i++) {
339
if (d->ui.meshNameButton->itemData(i).toString() == objName) {
340
d->ui.meshNameButton->setCurrentIndex(i);
341
onMeshNameButtonActivated(i);
347
void DlgEvaluateMeshImp::addViewProvider(const char* name,
348
const std::vector<Mesh::ElementIndex>& indices)
350
removeViewProvider(name);
353
auto vp = static_cast<ViewProviderMeshDefects*>(Base::Type::createInstanceByName(name));
354
assert(vp->isDerivedFrom<Gui::ViewProvider>());
355
vp->attach(d->meshFeature);
356
d->view->getViewer()->addViewProvider(vp);
357
vp->showDefects(indices);
362
void DlgEvaluateMeshImp::removeViewProvider(const char* name)
364
auto it = d->vp.find(name);
365
if (it != d->vp.end()) {
367
d->view->getViewer()->removeViewProvider(it->second);
374
void DlgEvaluateMeshImp::removeViewProviders()
376
for (const auto& it : d->vp) {
378
d->view->getViewer()->removeViewProvider(it.second);
385
void DlgEvaluateMeshImp::onMeshNameButtonActivated(int i)
387
QString item = d->ui.meshNameButton->itemData(i).toString();
389
d->meshFeature = nullptr;
390
std::vector<App::DocumentObject*> objs =
391
getDocument()->getObjectsOfType(Mesh::Feature::getClassTypeId());
392
for (auto obj : objs) {
393
if (item == QLatin1String(obj->getNameInDocument())) {
394
d->meshFeature = static_cast<Mesh::Feature*>(obj);
407
void DlgEvaluateMeshImp::refreshList()
409
QVector<QPair<QString, QString>> items;
410
if (this->getDocument()) {
411
std::vector<App::DocumentObject*> objs =
412
this->getDocument()->getObjectsOfType(Mesh::Feature::getClassTypeId());
413
for (auto obj : objs) {
414
items.push_back(qMakePair(QString::fromUtf8(obj->Label.getValue()),
415
QString::fromLatin1(obj->getNameInDocument())));
419
d->ui.meshNameButton->clear();
420
d->ui.meshNameButton->addItem(tr("No selection"));
421
for (const auto& item : items) {
422
d->ui.meshNameButton->addItem(item.first, item.second);
424
d->ui.meshNameButton->setDisabled(items.empty());
428
void DlgEvaluateMeshImp::showInformation()
430
d->ui.analyzeOrientationButton->setEnabled(true);
431
d->ui.analyzeDuplicatedFacesButton->setEnabled(true);
432
d->ui.analyzeDuplicatedPointsButton->setEnabled(true);
433
d->ui.analyzeNonmanifoldsButton->setEnabled(true);
434
d->ui.analyzeDegeneratedButton->setEnabled(true);
435
d->ui.analyzeIndicesButton->setEnabled(true);
436
d->ui.analyzeSelfIntersectionButton->setEnabled(true);
437
d->ui.analyzeFoldsButton->setEnabled(true);
438
d->ui.analyzeAllTogether->setEnabled(true);
440
if (d->meshFeature) {
441
const MeshKernel& rMesh = d->meshFeature->Mesh.getValue().getKernel();
442
d->ui.textLabel4->setText(QString::fromLatin1("%1").arg(rMesh.CountFacets()));
443
d->ui.textLabel5->setText(QString::fromLatin1("%1").arg(rMesh.CountEdges()));
444
d->ui.textLabel6->setText(QString::fromLatin1("%1").arg(rMesh.CountPoints()));
448
void DlgEvaluateMeshImp::cleanInformation()
450
d->ui.textLabel4->setText(tr("No information"));
451
d->ui.textLabel5->setText(tr("No information"));
452
d->ui.textLabel6->setText(tr("No information"));
453
d->ui.checkOrientationButton->setText(tr("No information"));
454
d->ui.checkDuplicatedFacesButton->setText(tr("No information"));
455
d->ui.checkDuplicatedPointsButton->setText(tr("No information"));
456
d->ui.checkNonmanifoldsButton->setText(tr("No information"));
457
d->ui.checkDegenerationButton->setText(tr("No information"));
458
d->ui.checkIndicesButton->setText(tr("No information"));
459
d->ui.checkSelfIntersectionButton->setText(tr("No information"));
460
d->ui.checkFoldsButton->setText(tr("No information"));
461
d->ui.analyzeOrientationButton->setDisabled(true);
462
d->ui.repairOrientationButton->setDisabled(true);
463
d->ui.analyzeDuplicatedFacesButton->setDisabled(true);
464
d->ui.repairDuplicatedFacesButton->setDisabled(true);
465
d->ui.analyzeDuplicatedPointsButton->setDisabled(true);
466
d->ui.repairDuplicatedPointsButton->setDisabled(true);
467
d->ui.analyzeNonmanifoldsButton->setDisabled(true);
468
d->ui.repairNonmanifoldsButton->setDisabled(true);
469
d->ui.analyzeDegeneratedButton->setDisabled(true);
470
d->ui.repairDegeneratedButton->setDisabled(true);
471
d->ui.analyzeIndicesButton->setDisabled(true);
472
d->ui.repairIndicesButton->setDisabled(true);
473
d->ui.analyzeSelfIntersectionButton->setDisabled(true);
474
d->ui.repairSelfIntersectionButton->setDisabled(true);
475
d->ui.analyzeFoldsButton->setDisabled(true);
476
d->ui.repairFoldsButton->setDisabled(true);
477
d->ui.analyzeAllTogether->setDisabled(true);
478
d->ui.repairAllTogether->setDisabled(true);
481
void DlgEvaluateMeshImp::onRefreshButtonClicked()
483
// Connect to application and active document
484
Gui::Document* gui = Gui::Application::Instance->activeDocument();
486
App::Document* doc = gui->getDocument();
488
// switch to the active document
489
if (doc && doc != this->getDocument()) {
491
removeViewProviders();
492
d->view = dynamic_cast<Gui::View3DInventor*>(gui->getActiveView());
499
void DlgEvaluateMeshImp::onCheckOrientationButtonClicked()
501
auto it = d->vp.find("MeshGui::ViewProviderMeshOrientation");
502
if (it != d->vp.end()) {
503
if (d->ui.checkOrientationButton->isChecked()) {
512
void DlgEvaluateMeshImp::onAnalyzeOrientationButtonClicked()
514
if (d->meshFeature) {
515
d->ui.analyzeOrientationButton->setEnabled(false);
516
qApp->processEvents();
517
qApp->setOverrideCursor(Qt::WaitCursor);
519
const MeshKernel& rMesh = d->meshFeature->Mesh.getValue().getKernel();
520
MeshEvalOrientation eval(rMesh);
521
std::vector<MeshCore::FacetIndex> inds = eval.GetIndices();
524
d->ui.checkOrientationButton->setText(tr("No flipped normals"));
525
d->ui.checkOrientationButton->setChecked(false);
526
d->ui.repairOrientationButton->setEnabled(false);
527
removeViewProvider("MeshGui::ViewProviderMeshOrientation");
530
d->ui.checkOrientationButton->setText(tr("%1 flipped normals").arg(inds.size()));
531
d->ui.checkOrientationButton->setChecked(true);
532
d->ui.repairOrientationButton->setEnabled(true);
533
d->ui.repairAllTogether->setEnabled(true);
534
addViewProvider("MeshGui::ViewProviderMeshOrientation", eval.GetIndices());
537
qApp->restoreOverrideCursor();
538
d->ui.analyzeOrientationButton->setEnabled(true);
542
void DlgEvaluateMeshImp::onRepairOrientationButtonClicked()
544
if (d->meshFeature) {
545
const char* docName = App::GetApplication().getDocumentName(d->meshFeature->getDocument());
546
const char* objName = d->meshFeature->getNameInDocument();
547
Gui::Document* doc = Gui::Application::Instance->getDocument(docName);
548
doc->openCommand(QT_TRANSLATE_NOOP("Command", "Harmonize normals"));
550
Gui::Command::doCommand(Gui::Command::App,
551
R"(App.getDocument("%s").getObject("%s").harmonizeNormals())",
555
catch (const Base::Exception& e) {
556
QMessageBox::warning(this, tr("Orientation"), QString::fromLatin1(e.what()));
559
doc->commitCommand();
560
doc->getDocument()->recompute();
562
d->ui.repairOrientationButton->setEnabled(false);
563
d->ui.checkOrientationButton->setChecked(false);
564
removeViewProvider("MeshGui::ViewProviderMeshOrientation");
568
void DlgEvaluateMeshImp::onCheckNonmanifoldsButtonClicked()
570
// non-manifold edges
571
std::map<std::string, ViewProviderMeshDefects*>::iterator it;
572
it = d->vp.find("MeshGui::ViewProviderMeshNonManifolds");
573
if (it != d->vp.end()) {
574
if (d->ui.checkNonmanifoldsButton->isChecked()) {
582
// non-manifold points
583
it = d->vp.find("MeshGui::ViewProviderMeshNonManifoldPoints");
584
if (it != d->vp.end()) {
585
if (d->ui.checkNonmanifoldsButton->isChecked()) {
594
void DlgEvaluateMeshImp::onAnalyzeNonmanifoldsButtonClicked()
596
if (d->meshFeature) {
597
d->ui.analyzeNonmanifoldsButton->setEnabled(false);
598
qApp->processEvents();
599
qApp->setOverrideCursor(Qt::WaitCursor);
601
const MeshKernel& rMesh = d->meshFeature->Mesh.getValue().getKernel();
602
MeshEvalTopology f_eval(rMesh);
603
bool ok1 = f_eval.Evaluate();
605
std::vector<Mesh::PointIndex> point_indices;
607
if (d->checkNonManfoldPoints) {
608
MeshEvalPointManifolds p_eval(rMesh);
609
ok2 = p_eval.Evaluate();
611
point_indices = p_eval.GetIndices();
616
d->ui.checkNonmanifoldsButton->setText(tr("No non-manifolds"));
617
d->ui.checkNonmanifoldsButton->setChecked(false);
618
d->ui.repairNonmanifoldsButton->setEnabled(false);
619
removeViewProvider("MeshGui::ViewProviderMeshNonManifolds");
620
removeViewProvider("MeshGui::ViewProviderMeshNonManifoldPoints");
623
d->ui.checkNonmanifoldsButton->setText(
624
tr("%1 non-manifolds").arg(f_eval.CountManifolds() + point_indices.size()));
625
d->ui.checkNonmanifoldsButton->setChecked(true);
626
d->ui.repairNonmanifoldsButton->setEnabled(true);
627
d->ui.repairAllTogether->setEnabled(true);
630
const std::vector<std::pair<Mesh::FacetIndex, Mesh::FacetIndex>>& inds =
632
std::vector<Mesh::FacetIndex> indices;
633
indices.reserve(2 * inds.size());
634
std::vector<std::pair<Mesh::FacetIndex, Mesh::FacetIndex>>::const_iterator it;
635
for (it = inds.begin(); it != inds.end(); ++it) {
636
indices.push_back(it->first);
637
indices.push_back(it->second);
640
addViewProvider("MeshGui::ViewProviderMeshNonManifolds", indices);
644
addViewProvider("MeshGui::ViewProviderMeshNonManifoldPoints", point_indices);
648
qApp->restoreOverrideCursor();
649
d->ui.analyzeNonmanifoldsButton->setEnabled(true);
653
void DlgEvaluateMeshImp::onRepairNonmanifoldsButtonClicked()
655
if (d->meshFeature) {
656
const char* docName = App::GetApplication().getDocumentName(d->meshFeature->getDocument());
657
const char* objName = d->meshFeature->getNameInDocument();
658
Gui::Document* doc = Gui::Application::Instance->getDocument(docName);
659
doc->openCommand(QT_TRANSLATE_NOOP("Command", "Remove non-manifolds"));
661
Gui::Command::doCommand(Gui::Command::App,
662
R"(App.getDocument("%s").getObject("%s").removeNonManifolds())",
666
if (d->checkNonManfoldPoints) {
667
Gui::Command::doCommand(
669
R"(App.getDocument("%s").getObject("%s").removeNonManifoldPoints())",
674
catch (const Base::Exception& e) {
675
QMessageBox::warning(this, tr("Non-manifolds"), QString::fromLatin1(e.what()));
678
QMessageBox::warning(this, tr("Non-manifolds"), tr("Cannot remove non-manifolds"));
681
doc->commitCommand();
682
doc->getDocument()->recompute();
684
d->ui.repairNonmanifoldsButton->setEnabled(false);
685
d->ui.checkNonmanifoldsButton->setChecked(false);
686
removeViewProvider("MeshGui::ViewProviderMeshNonManifolds");
687
removeViewProvider("MeshGui::ViewProviderMeshNonManifoldsPoints");
691
void DlgEvaluateMeshImp::onCheckIndicesButtonClicked()
693
auto it = d->vp.find("MeshGui::ViewProviderMeshIndices");
694
if (it != d->vp.end()) {
695
if (d->ui.checkIndicesButton->isChecked()) {
704
void DlgEvaluateMeshImp::onAnalyzeIndicesButtonClicked()
706
if (d->meshFeature) {
707
d->ui.analyzeIndicesButton->setEnabled(false);
708
qApp->processEvents();
709
qApp->setOverrideCursor(Qt::WaitCursor);
711
const MeshKernel& rMesh = d->meshFeature->Mesh.getValue().getKernel();
712
MeshEvalRangeFacet rf(rMesh);
713
MeshEvalRangePoint rp(rMesh);
714
MeshEvalCorruptedFacets cf(rMesh);
715
MeshEvalNeighbourhood nb(rMesh);
717
if (!rf.Evaluate()) {
718
d->ui.checkIndicesButton->setText(tr("Invalid face indices"));
719
d->ui.checkIndicesButton->setChecked(true);
720
d->ui.repairIndicesButton->setEnabled(true);
721
d->ui.repairAllTogether->setEnabled(true);
722
addViewProvider("MeshGui::ViewProviderMeshIndices", rf.GetIndices());
724
else if (!rp.Evaluate()) {
725
d->ui.checkIndicesButton->setText(tr("Invalid point indices"));
726
d->ui.checkIndicesButton->setChecked(true);
727
d->ui.repairIndicesButton->setEnabled(true);
728
d->ui.repairAllTogether->setEnabled(true);
729
// addViewProvider("MeshGui::ViewProviderMeshIndices", rp.GetIndices());
731
else if (!cf.Evaluate()) {
732
d->ui.checkIndicesButton->setText(tr("Multiple point indices"));
733
d->ui.checkIndicesButton->setChecked(true);
734
d->ui.repairIndicesButton->setEnabled(true);
735
d->ui.repairAllTogether->setEnabled(true);
736
addViewProvider("MeshGui::ViewProviderMeshIndices", cf.GetIndices());
738
else if (!nb.Evaluate()) {
739
d->ui.checkIndicesButton->setText(tr("Invalid neighbour indices"));
740
d->ui.checkIndicesButton->setChecked(true);
741
d->ui.repairIndicesButton->setEnabled(true);
742
d->ui.repairAllTogether->setEnabled(true);
743
addViewProvider("MeshGui::ViewProviderMeshIndices", nb.GetIndices());
746
d->ui.checkIndicesButton->setText(tr("No invalid indices"));
747
d->ui.checkIndicesButton->setChecked(false);
748
d->ui.repairIndicesButton->setEnabled(false);
749
removeViewProvider("MeshGui::ViewProviderMeshIndices");
752
qApp->restoreOverrideCursor();
753
d->ui.analyzeIndicesButton->setEnabled(true);
757
void DlgEvaluateMeshImp::onRepairIndicesButtonClicked()
759
if (d->meshFeature) {
760
const char* docName = App::GetApplication().getDocumentName(d->meshFeature->getDocument());
761
const char* objName = d->meshFeature->getNameInDocument();
762
Gui::Document* doc = Gui::Application::Instance->getDocument(docName);
763
doc->openCommand(QT_TRANSLATE_NOOP("Command", "Fix indices"));
765
Gui::Command::doCommand(Gui::Command::App,
766
R"(App.getDocument("%s").getObject("%s").fixIndices())",
770
catch (const Base::Exception& e) {
771
QMessageBox::warning(this, tr("Indices"), QString::fromLatin1(e.what()));
774
doc->commitCommand();
775
doc->getDocument()->recompute();
777
d->ui.repairIndicesButton->setEnabled(false);
778
d->ui.checkIndicesButton->setChecked(false);
779
removeViewProvider("MeshGui::ViewProviderMeshIndices");
783
void DlgEvaluateMeshImp::onCheckDegenerationButtonClicked()
785
auto it = d->vp.find("MeshGui::ViewProviderMeshDegenerations");
786
if (it != d->vp.end()) {
787
if (d->ui.checkDegenerationButton->isChecked()) {
796
void DlgEvaluateMeshImp::onAnalyzeDegeneratedButtonClicked()
798
if (d->meshFeature) {
799
d->ui.analyzeDegeneratedButton->setEnabled(false);
800
qApp->processEvents();
801
qApp->setOverrideCursor(Qt::WaitCursor);
803
const MeshKernel& rMesh = d->meshFeature->Mesh.getValue().getKernel();
804
MeshEvalDegeneratedFacets eval(rMesh, d->epsilonDegenerated);
805
std::vector<Mesh::FacetIndex> degen = eval.GetIndices();
808
d->ui.checkDegenerationButton->setText(tr("No degenerations"));
809
d->ui.checkDegenerationButton->setChecked(false);
810
d->ui.repairDegeneratedButton->setEnabled(false);
811
removeViewProvider("MeshGui::ViewProviderMeshDegenerations");
814
d->ui.checkDegenerationButton->setText(tr("%1 degenerated faces").arg(degen.size()));
815
d->ui.checkDegenerationButton->setChecked(true);
816
d->ui.repairDegeneratedButton->setEnabled(true);
817
d->ui.repairAllTogether->setEnabled(true);
818
addViewProvider("MeshGui::ViewProviderMeshDegenerations", degen);
821
qApp->restoreOverrideCursor();
822
d->ui.analyzeDegeneratedButton->setEnabled(true);
826
void DlgEvaluateMeshImp::onRepairDegeneratedButtonClicked()
828
if (d->meshFeature) {
829
const char* docName = App::GetApplication().getDocumentName(d->meshFeature->getDocument());
830
const char* objName = d->meshFeature->getNameInDocument();
831
Gui::Document* doc = Gui::Application::Instance->getDocument(docName);
832
doc->openCommand(QT_TRANSLATE_NOOP("Command", "Remove degenerated faces"));
834
Gui::Command::doCommand(Gui::Command::App,
835
R"(App.getDocument("%s").getObject("%s").fixDegenerations(%f))",
838
d->epsilonDegenerated);
840
catch (const Base::Exception& e) {
841
QMessageBox::warning(this, tr("Degenerations"), QString::fromLatin1(e.what()));
844
doc->commitCommand();
845
doc->getDocument()->recompute();
847
d->ui.repairDegeneratedButton->setEnabled(false);
848
d->ui.checkDegenerationButton->setChecked(false);
849
removeViewProvider("MeshGui::ViewProviderMeshDegenerations");
853
void DlgEvaluateMeshImp::onCheckDuplicatedFacesButtonClicked()
855
auto it = d->vp.find("MeshGui::ViewProviderMeshDuplicatedFaces");
856
if (it != d->vp.end()) {
857
if (d->ui.checkDuplicatedFacesButton->isChecked()) {
866
void DlgEvaluateMeshImp::onAnalyzeDuplicatedFacesButtonClicked()
868
if (d->meshFeature) {
869
d->ui.analyzeDuplicatedFacesButton->setEnabled(false);
870
qApp->processEvents();
871
qApp->setOverrideCursor(Qt::WaitCursor);
873
const MeshKernel& rMesh = d->meshFeature->Mesh.getValue().getKernel();
874
MeshEvalDuplicateFacets eval(rMesh);
875
std::vector<Mesh::FacetIndex> dupl = eval.GetIndices();
878
d->ui.checkDuplicatedFacesButton->setText(tr("No duplicated faces"));
879
d->ui.checkDuplicatedFacesButton->setChecked(false);
880
d->ui.repairDuplicatedFacesButton->setEnabled(false);
881
removeViewProvider("MeshGui::ViewProviderMeshDuplicatedFaces");
884
d->ui.checkDuplicatedFacesButton->setText(tr("%1 duplicated faces").arg(dupl.size()));
885
d->ui.checkDuplicatedFacesButton->setChecked(true);
886
d->ui.repairDuplicatedFacesButton->setEnabled(true);
887
d->ui.repairAllTogether->setEnabled(true);
889
addViewProvider("MeshGui::ViewProviderMeshDuplicatedFaces", dupl);
892
qApp->restoreOverrideCursor();
893
d->ui.analyzeDuplicatedFacesButton->setEnabled(true);
897
void DlgEvaluateMeshImp::onRepairDuplicatedFacesButtonClicked()
899
if (d->meshFeature) {
900
const char* docName = App::GetApplication().getDocumentName(d->meshFeature->getDocument());
901
const char* objName = d->meshFeature->getNameInDocument();
902
Gui::Document* doc = Gui::Application::Instance->getDocument(docName);
903
doc->openCommand(QT_TRANSLATE_NOOP("Command", "Remove duplicated faces"));
905
Gui::Command::doCommand(
907
R"(App.getDocument("%s").getObject("%s").removeDuplicatedFacets())",
911
catch (const Base::Exception& e) {
912
QMessageBox::warning(this, tr("Duplicated faces"), QString::fromLatin1(e.what()));
915
doc->commitCommand();
916
doc->getDocument()->recompute();
918
d->ui.repairDuplicatedFacesButton->setEnabled(false);
919
d->ui.checkDuplicatedFacesButton->setChecked(false);
920
removeViewProvider("MeshGui::ViewProviderMeshDuplicatedFaces");
924
void DlgEvaluateMeshImp::onCheckDuplicatedPointsButtonClicked()
926
auto it = d->vp.find("MeshGui::ViewProviderMeshDuplicatedPoints");
927
if (it != d->vp.end()) {
928
if (d->ui.checkDuplicatedPointsButton->isChecked()) {
937
void DlgEvaluateMeshImp::onAnalyzeDuplicatedPointsButtonClicked()
939
if (d->meshFeature) {
940
d->ui.analyzeDuplicatedPointsButton->setEnabled(false);
941
qApp->processEvents();
942
qApp->setOverrideCursor(Qt::WaitCursor);
944
const MeshKernel& rMesh = d->meshFeature->Mesh.getValue().getKernel();
945
MeshEvalDuplicatePoints eval(rMesh);
947
if (eval.Evaluate()) {
948
d->ui.checkDuplicatedPointsButton->setText(tr("No duplicated points"));
949
d->ui.checkDuplicatedPointsButton->setChecked(false);
950
d->ui.repairDuplicatedPointsButton->setEnabled(false);
951
removeViewProvider("MeshGui::ViewProviderMeshDuplicatedPoints");
954
d->ui.checkDuplicatedPointsButton->setText(tr("Duplicated points"));
955
d->ui.checkDuplicatedPointsButton->setChecked(true);
956
d->ui.repairDuplicatedPointsButton->setEnabled(true);
957
d->ui.repairAllTogether->setEnabled(true);
958
addViewProvider("MeshGui::ViewProviderMeshDuplicatedPoints", eval.GetIndices());
961
qApp->restoreOverrideCursor();
962
d->ui.analyzeDuplicatedPointsButton->setEnabled(true);
966
void DlgEvaluateMeshImp::onRepairDuplicatedPointsButtonClicked()
968
if (d->meshFeature) {
969
const char* docName = App::GetApplication().getDocumentName(d->meshFeature->getDocument());
970
const char* objName = d->meshFeature->getNameInDocument();
971
Gui::Document* doc = Gui::Application::Instance->getDocument(docName);
972
doc->openCommand(QT_TRANSLATE_NOOP("Command", "Remove duplicated points"));
974
Gui::Command::doCommand(
976
R"(App.getDocument("%s").getObject("%s").removeDuplicatedPoints())",
980
catch (const Base::Exception& e) {
981
QMessageBox::warning(this, tr("Duplicated points"), QString::fromLatin1(e.what()));
984
doc->commitCommand();
985
doc->getDocument()->recompute();
987
d->ui.repairDuplicatedPointsButton->setEnabled(false);
988
d->ui.checkDuplicatedPointsButton->setChecked(false);
989
removeViewProvider("MeshGui::ViewProviderMeshDuplicatedPoints");
993
void DlgEvaluateMeshImp::onCheckSelfIntersectionButtonClicked()
995
auto it = d->vp.find("MeshGui::ViewProviderMeshSelfIntersections");
996
if (it != d->vp.end()) {
997
if (d->ui.checkSelfIntersectionButton->isChecked()) {
1006
void DlgEvaluateMeshImp::onAnalyzeSelfIntersectionButtonClicked()
1008
if (d->meshFeature) {
1009
d->ui.analyzeSelfIntersectionButton->setEnabled(false);
1010
qApp->processEvents();
1011
qApp->setOverrideCursor(Qt::WaitCursor);
1013
const MeshKernel& rMesh = d->meshFeature->Mesh.getValue().getKernel();
1014
MeshEvalSelfIntersection eval(rMesh);
1015
std::vector<std::pair<Mesh::FacetIndex, Mesh::FacetIndex>> intersection;
1017
eval.GetIntersections(intersection);
1019
catch (const Base::AbortException&) {
1020
Base::Console().Message("The self-intersection analysis was aborted by the user\n");
1023
if (intersection.empty()) {
1024
d->ui.checkSelfIntersectionButton->setText(tr("No self-intersections"));
1025
d->ui.checkSelfIntersectionButton->setChecked(false);
1026
d->ui.repairSelfIntersectionButton->setEnabled(false);
1027
removeViewProvider("MeshGui::ViewProviderMeshSelfIntersections");
1030
d->ui.checkSelfIntersectionButton->setText(tr("Self-intersections"));
1031
d->ui.checkSelfIntersectionButton->setChecked(true);
1032
d->ui.repairSelfIntersectionButton->setEnabled(true);
1033
d->ui.repairAllTogether->setEnabled(true);
1035
std::vector<Mesh::FacetIndex> indices;
1036
indices.reserve(2 * intersection.size());
1037
std::vector<std::pair<Mesh::FacetIndex, Mesh::FacetIndex>>::iterator it;
1038
for (it = intersection.begin(); it != intersection.end(); ++it) {
1039
indices.push_back(it->first);
1040
indices.push_back(it->second);
1043
addViewProvider("MeshGui::ViewProviderMeshSelfIntersections", indices);
1044
d->self_intersections.swap(indices);
1047
qApp->restoreOverrideCursor();
1048
d->ui.analyzeSelfIntersectionButton->setEnabled(true);
1052
void DlgEvaluateMeshImp::onRepairSelfIntersectionButtonClicked()
1054
if (d->meshFeature) {
1055
const char* docName = App::GetApplication().getDocumentName(d->meshFeature->getDocument());
1056
Gui::Document* doc = Gui::Application::Instance->getDocument(docName);
1057
doc->openCommand(QT_TRANSLATE_NOOP("Command", "Fix self-intersections"));
1059
Mesh::MeshObject* mesh = d->meshFeature->Mesh.startEditing();
1060
mesh->removeSelfIntersections(d->self_intersections);
1061
d->meshFeature->Mesh.finishEditing();
1062
doc->commitCommand();
1063
doc->getDocument()->recompute();
1065
d->ui.repairSelfIntersectionButton->setEnabled(false);
1066
d->ui.checkSelfIntersectionButton->setChecked(false);
1067
removeViewProvider("MeshGui::ViewProviderMeshSelfIntersections");
1071
void DlgEvaluateMeshImp::onCheckFoldsButtonClicked()
1073
auto it = d->vp.find("MeshGui::ViewProviderMeshFolds");
1074
if (it != d->vp.end()) {
1075
if (d->ui.checkFoldsButton->isChecked()) {
1084
void DlgEvaluateMeshImp::onAnalyzeFoldsButtonClicked()
1086
if (d->meshFeature) {
1087
d->ui.analyzeFoldsButton->setEnabled(false);
1088
qApp->processEvents();
1089
qApp->setOverrideCursor(Qt::WaitCursor);
1091
const MeshKernel& rMesh = d->meshFeature->Mesh.getValue().getKernel();
1092
MeshEvalFoldsOnSurface s_eval(rMesh);
1093
MeshEvalFoldsOnBoundary b_eval(rMesh);
1094
MeshEvalFoldOversOnSurface f_eval(rMesh);
1095
bool ok1 = s_eval.Evaluate();
1096
bool ok2 = b_eval.Evaluate();
1097
bool ok3 = f_eval.Evaluate();
1099
if (ok1 && ok2 && ok3) {
1100
d->ui.checkFoldsButton->setText(tr("No folds on surface"));
1101
d->ui.checkFoldsButton->setChecked(false);
1102
d->ui.repairFoldsButton->setEnabled(false);
1103
removeViewProvider("MeshGui::ViewProviderMeshFolds");
1106
std::vector<Mesh::FacetIndex> inds = f_eval.GetIndices();
1107
std::vector<Mesh::FacetIndex> inds1 = s_eval.GetIndices();
1108
std::vector<Mesh::FacetIndex> inds2 = b_eval.GetIndices();
1109
inds.insert(inds.end(), inds1.begin(), inds1.end());
1110
inds.insert(inds.end(), inds2.begin(), inds2.end());
1112
// remove duplicates
1113
std::sort(inds.begin(), inds.end());
1114
inds.erase(std::unique(inds.begin(), inds.end()), inds.end());
1116
d->ui.checkFoldsButton->setText(tr("%1 folds on surface").arg(inds.size()));
1117
d->ui.checkFoldsButton->setChecked(true);
1118
d->ui.repairFoldsButton->setEnabled(true);
1119
d->ui.repairAllTogether->setEnabled(true);
1120
addViewProvider("MeshGui::ViewProviderMeshFolds", inds);
1123
qApp->restoreOverrideCursor();
1124
d->ui.analyzeFoldsButton->setEnabled(true);
1128
void DlgEvaluateMeshImp::onRepairFoldsButtonClicked()
1130
if (d->meshFeature) {
1131
const char* docName = App::GetApplication().getDocumentName(d->meshFeature->getDocument());
1132
const char* objName = d->meshFeature->getNameInDocument();
1133
Gui::Document* doc = Gui::Application::Instance->getDocument(docName);
1134
qApp->setOverrideCursor(Qt::WaitCursor);
1135
doc->openCommand(QT_TRANSLATE_NOOP("Command", "Remove folds"));
1137
Gui::Command::doCommand(
1139
R"(App.getDocument("%s").getObject("%s").removeFoldsOnSurface())",
1143
catch (const Base::Exception& e) {
1144
QMessageBox::warning(this, tr("Folds"), QString::fromLatin1(e.what()));
1147
doc->commitCommand();
1148
doc->getDocument()->recompute();
1150
qApp->restoreOverrideCursor();
1151
d->ui.repairFoldsButton->setEnabled(false);
1152
d->ui.checkFoldsButton->setChecked(false);
1153
removeViewProvider("MeshGui::ViewProviderMeshFolds");
1157
void DlgEvaluateMeshImp::onAnalyzeAllTogetherClicked()
1159
onAnalyzeOrientationButtonClicked();
1160
onAnalyzeDuplicatedFacesButtonClicked();
1161
onAnalyzeDuplicatedPointsButtonClicked();
1162
onAnalyzeNonmanifoldsButtonClicked();
1163
onAnalyzeDegeneratedButtonClicked();
1164
onAnalyzeIndicesButtonClicked();
1165
onAnalyzeSelfIntersectionButtonClicked();
1166
if (d->enableFoldsCheck) {
1167
onAnalyzeFoldsButtonClicked();
1171
void DlgEvaluateMeshImp::onRepairAllTogetherClicked()
1174
if (d->meshFeature) {
1176
const char* docName = App::GetApplication().getDocumentName(d->meshFeature->getDocument());
1177
const char* objName = d->meshFeature->getNameInDocument();
1178
Gui::Document* doc = Gui::Application::Instance->getDocument(docName);
1179
doc->openCommand(QT_TRANSLATE_NOOP("Command", "Repair mesh"));
1184
const MeshKernel& rMesh = d->meshFeature->Mesh.getValue().getKernel();
1189
MeshEvalSelfIntersection eval(rMesh);
1190
if (self && !eval.Evaluate()) {
1191
Gui::Command::doCommand(Gui::Command::App,
1192
"App.getDocument(\"%s\").getObject(\"%s\").fixSelfIntersections()",
1197
self = false; // once no self-intersections found do not repeat it later on
1199
qApp->processEvents();
1201
if (d->enableFoldsCheck) {
1202
MeshEvalFoldsOnSurface s_eval(rMesh);
1203
MeshEvalFoldsOnBoundary b_eval(rMesh);
1204
MeshEvalFoldOversOnSurface f_eval(rMesh);
1205
if (!s_eval.Evaluate() || !b_eval.Evaluate() || !f_eval.Evaluate()) {
1206
Gui::Command::doCommand(Gui::Command::App,
1207
"App.getDocument(\"%s\").getObject(\"%s\").removeFoldsOnSurface()",
1211
qApp->processEvents();
1214
MeshEvalOrientation eval(rMesh);
1215
if (!eval.Evaluate()) {
1216
Gui::Command::doCommand(Gui::Command::App,
1217
"App.getDocument(\"%s\").getObject(\"%s\").harmonizeNormals()",
1221
qApp->processEvents();
1224
MeshEvalTopology eval(rMesh);
1225
if (!eval.Evaluate()) {
1226
Gui::Command::doCommand(Gui::Command::App,
1227
"App.getDocument(\"%s\").getObject(\"%s\").removeNonManifolds()",
1231
qApp->processEvents();
1234
MeshEvalRangeFacet rf(rMesh);
1235
MeshEvalRangePoint rp(rMesh);
1236
MeshEvalCorruptedFacets cf(rMesh);
1237
MeshEvalNeighbourhood nb(rMesh);
1238
if (!rf.Evaluate() || !rp.Evaluate() || !cf.Evaluate() || !nb.Evaluate()) {
1239
Gui::Command::doCommand(Gui::Command::App,
1240
"App.getDocument(\"%s\").getObject(\"%s\").fixIndices()",
1246
MeshEvalDegeneratedFacets eval(rMesh, d->epsilonDegenerated);
1247
if (!eval.Evaluate()) {
1248
Gui::Command::doCommand(Gui::Command::App,
1249
"App.getDocument(\"%s\").getObject(\"%s\").fixDegenerations(%f)",
1250
docName, objName, d->epsilonDegenerated);
1253
qApp->processEvents();
1256
MeshEvalDuplicateFacets eval(rMesh);
1257
if (!eval.Evaluate()) {
1258
Gui::Command::doCommand(Gui::Command::App,
1259
"App.getDocument(\"%s\").getObject(\"%s\").removeDuplicatedFacets()",
1263
qApp->processEvents();
1266
MeshEvalDuplicatePoints eval(rMesh);
1267
if (!eval.Evaluate()) {
1268
Gui::Command::doCommand(Gui::Command::App,
1269
"App.getDocument(\"%s\").getObject(\"%s\").removeDuplicatedPoints()",
1273
qApp->processEvents();
1275
} while(d->ui.checkRepeatButton->isChecked() && run && (--max_iter > 0));
1277
catch (const Base::Exception& e) {
1278
QMessageBox::warning(this, tr("Mesh repair"), QString::fromLatin1(e.what()));
1281
QMessageBox::warning(this, tr("Mesh repair"), QString::fromLatin1("Unknown error occurred."));
1284
doc->commitCommand();
1285
doc->getDocument()->recompute();
1290
void DlgEvaluateMeshImp::onButtonBoxClicked(QAbstractButton* button)
1292
QDialogButtonBox::StandardButton type = d->ui.buttonBox->standardButton(button);
1293
if (type == QDialogButtonBox::Open) {
1294
DlgEvaluateSettings dlg(this);
1295
dlg.setNonmanifoldPointsChecked(d->checkNonManfoldPoints);
1296
dlg.setFoldsChecked(d->enableFoldsCheck);
1297
dlg.setDegeneratedFacetsChecked(d->strictlyDegenerated);
1298
if (dlg.exec() == QDialog::Accepted) {
1299
d->checkNonManfoldPoints = dlg.isNonmanifoldPointsChecked();
1300
d->enableFoldsCheck = dlg.isFoldsChecked();
1301
d->showFoldsFunction(d->enableFoldsCheck);
1302
d->strictlyDegenerated = dlg.isDegeneratedFacetsChecked();
1303
if (d->strictlyDegenerated) {
1304
d->epsilonDegenerated = 0.0F;
1307
d->epsilonDegenerated = MeshCore::MeshDefinitions::_fMinPointDistanceP2;
1311
else if (type == QDialogButtonBox::Reset) {
1312
removeViewProviders();
1315
d->self_intersections.clear();
1316
QList<QCheckBox*> cbs = this->findChildren<QCheckBox*>();
1317
Q_FOREACH (QCheckBox* cb, cbs) {
1318
cb->setChecked(false);
1323
// -------------------------------------------------------------
1325
/* TRANSLATOR MeshGui::DockEvaluateMeshImp */
1327
#if 0 // needed for Qt's lupdate utility
1328
qApp->translate("QDockWidget", "Evaluate & Repair Mesh");
1331
DockEvaluateMeshImp* DockEvaluateMeshImp::_instance = nullptr;
1333
DockEvaluateMeshImp* DockEvaluateMeshImp::instance()
1337
_instance = new DockEvaluateMeshImp(Gui::getMainWindow());
1338
_instance->setSizeGripEnabled(false);
1344
void DockEvaluateMeshImp::destruct()
1347
DockEvaluateMeshImp* pTmp = _instance;
1348
_instance = nullptr;
1353
bool DockEvaluateMeshImp::hasInstance()
1355
return _instance != nullptr;
1359
* Constructs a DockEvaluateMeshImp which is a child of 'parent', with the
1360
* name 'name' and widget flags set to 'f'
1362
DockEvaluateMeshImp::DockEvaluateMeshImp(QWidget* parent, Qt::WindowFlags fl)
1363
: DlgEvaluateMeshImp(parent, fl)
1365
scrollArea = new QScrollArea(); // NOLINT
1366
scrollArea->setObjectName(QLatin1String("scrollArea"));
1367
scrollArea->setFrameShape(QFrame::NoFrame);
1368
scrollArea->setFrameShadow(QFrame::Plain);
1369
scrollArea->setWidgetResizable(true);
1370
scrollArea->setWidget(this);
1372
// embed this dialog into a dockable widget container
1373
Gui::DockWindowManager* pDockMgr = Gui::DockWindowManager::instance();
1374
// use Qt macro for preparing for translation stuff (but not translating yet)
1376
pDockMgr->addDockWindow("Evaluate & Repair Mesh", scrollArea, Qt::RightDockWidgetArea);
1377
dw->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
1382
* Destroys the object and frees any allocated resources
1384
DockEvaluateMeshImp::~DockEvaluateMeshImp()
1386
_instance = nullptr;
1390
* Destroys the dock window this object is embedded into without destroying itself.
1392
void DockEvaluateMeshImp::closeEvent(QCloseEvent* event)
1395
// closes the dock window
1396
Gui::DockWindowManager* pDockMgr = Gui::DockWindowManager::instance();
1397
pDockMgr->removeDockWindow(scrollArea);
1399
// make sure to also delete the scroll area
1400
scrollArea->setWidget(nullptr);
1401
scrollArea->deleteLater();
1405
* Returns an appropriate size hint for the dock window.
1407
QSize DockEvaluateMeshImp::sizeHint() const
1412
#include "moc_DlgEvaluateMeshImp.cpp"