FreeCAD

Форк
0
/
TaskFillingEdge.cpp 
665 строк · 23.7 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2017 Werner Mayer <wmayer[at]users.sourceforge.net>     *
3
 *   Copyright (c) 2017 Christophe Grellier <cg[at]grellier.fr>            *
4
 *                                                                         *
5
 *   This file is part of the FreeCAD CAx development system.              *
6
 *                                                                         *
7
 *   This library is free software; you can redistribute it and/or         *
8
 *   modify it under the terms of the GNU Library General Public           *
9
 *   License as published by the Free Software Foundation; either          *
10
 *   version 2 of the License, or (at your option) any later version.      *
11
 *                                                                         *
12
 *   This library  is distributed in the hope that it will be useful,      *
13
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
15
 *   GNU Library General Public License for more details.                  *
16
 *                                                                         *
17
 *   You should have received a copy of the GNU Library General Public     *
18
 *   License along with this library; see the file COPYING.LIB. If not,    *
19
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
20
 *   Suite 330, Boston, MA  02111-1307, USA                                *
21
 *                                                                         *
22
 ***************************************************************************/
23

24
#include "PreCompiled.h"
25
#ifndef _PreComp_
26
#include <QAction>
27
#include <QMessageBox>
28
#include <QTimer>
29

30
#include <GeomAbs_Shape.hxx>
31
#include <TopExp.hxx>
32
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
33
#include <TopTools_IndexedMapOfShape.hxx>
34
#include <TopTools_ListIteratorOfListOfShape.hxx>
35
#endif
36

37
#include <App/Document.h>
38
#include <Gui/Application.h>
39
#include <Gui/Command.h>
40
#include <Gui/Document.h>
41
#include <Gui/SelectionObject.h>
42
#include <Gui/Widgets.h>
43
#include <Mod/Part/Gui/ViewProvider.h>
44

45
#include "TaskFilling.h"
46
#include "TaskFillingEdge.h"
47
#include "ui_TaskFillingEdge.h"
48

49

50
using namespace SurfaceGui;
51

52
namespace SurfaceGui
53
{
54

55
class FillingEdgePanel::ShapeSelection: public Gui::SelectionFilterGate
56
{
57
public:
58
    ShapeSelection(FillingEdgePanel::SelectionMode& mode, Surface::Filling* editedObject)
59
        : Gui::SelectionFilterGate(nullPointer())
60
        , mode(mode)
61
        , editedObject(editedObject)
62
    {}
63
    ~ShapeSelection() override
64
    {
65
        mode = FillingEdgePanel::None;
66
    }
67
    /**
68
     * Allow the user to pick only edges.
69
     */
70
    bool allow(App::Document*, App::DocumentObject* pObj, const char* sSubName) override
71
    {
72
        // don't allow references to itself
73
        if (pObj == editedObject) {
74
            return false;
75
        }
76
        if (!pObj->isDerivedFrom(Part::Feature::getClassTypeId())) {
77
            return false;
78
        }
79

80
        if (!sSubName || sSubName[0] == '\0') {
81
            return false;
82
        }
83

84
        switch (mode) {
85
            case FillingEdgePanel::AppendEdge:
86
                return allowEdge(true, pObj, sSubName);
87
            case FillingEdgePanel::RemoveEdge:
88
                return allowEdge(false, pObj, sSubName);
89
            default:
90
                return false;
91
        }
92
    }
93

94
private:
95
    bool allowEdge(bool appendEdges, App::DocumentObject* pObj, const char* sSubName)
96
    {
97
        std::string element(sSubName);
98
        if (element.substr(0, 4) != "Edge") {
99
            return false;
100
        }
101

102
        auto links = editedObject->UnboundEdges.getSubListValues();
103
        for (const auto& it : links) {
104
            if (it.first == pObj) {
105
                for (const auto& jt : it.second) {
106
                    if (jt == sSubName) {
107
                        return !appendEdges;
108
                    }
109
                }
110
            }
111
        }
112

113
        return appendEdges;
114
    }
115

116
private:
117
    FillingEdgePanel::SelectionMode& mode;
118
    Surface::Filling* editedObject;
119
};
120

121
// ----------------------------------------------------------------------------
122

123
FillingEdgePanel::FillingEdgePanel(ViewProviderFilling* vp, Surface::Filling* obj)
124
{
125
    ui = new Ui_TaskFillingEdge();
126
    ui->setupUi(this);
127
    setupConnections();
128

129
    selectionMode = None;
130
    this->vp = vp;
131
    checkCommand = true;
132
    setEditedObject(obj);
133

134
    // Create context menu
135
    QAction* action = new QAction(tr("Remove"), this);
136
    action->setShortcut(QString::fromLatin1("Del"));
137
    action->setShortcutContext(Qt::WidgetShortcut);
138
    ui->listUnbound->addAction(action);
139
    connect(action, &QAction::triggered, this, &FillingEdgePanel::onDeleteUnboundEdge);
140
    ui->listUnbound->setContextMenuPolicy(Qt::ActionsContextMenu);
141
}
142

143
/*
144
 *  Destroys the object and frees any allocated resources
145
 */
146
FillingEdgePanel::~FillingEdgePanel()
147
{
148
    // no need to delete child widgets, Qt does it all for us
149
    delete ui;
150
    Gui::Selection().rmvSelectionGate();
151
}
152

153
void FillingEdgePanel::setupConnections()
154
{
155
    connect(ui->buttonUnboundEdgeAdd,
156
            &QToolButton::toggled,
157
            this,
158
            &FillingEdgePanel::onButtonUnboundEdgeAddToggled);
159
    connect(ui->buttonUnboundEdgeRemove,
160
            &QToolButton::toggled,
161
            this,
162
            &FillingEdgePanel::onButtonUnboundEdgeRemoveToggled);
163
    connect(ui->listUnbound,
164
            &QListWidget::itemDoubleClicked,
165
            this,
166
            &FillingEdgePanel::onListUnboundItemDoubleClicked);
167
    connect(ui->buttonUnboundAccept,
168
            &QPushButton::clicked,
169
            this,
170
            &FillingEdgePanel::onButtonUnboundAcceptClicked);
171
    connect(ui->buttonUnboundIgnore,
172
            &QPushButton::clicked,
173
            this,
174
            &FillingEdgePanel::onButtonUnboundIgnoreClicked);
175
}
176

177
void FillingEdgePanel::appendButtons(Gui::ButtonGroup* buttonGroup)
178
{
179
    buttonGroup->addButton(ui->buttonUnboundEdgeAdd, int(SelectionMode::AppendEdge));
180
    buttonGroup->addButton(ui->buttonUnboundEdgeRemove, int(SelectionMode::RemoveEdge));
181
}
182

183
// stores object pointer, its old fill type and adjusts radio buttons according to it.
184
void FillingEdgePanel::setEditedObject(Surface::Filling* fea)
185
{
186
    editedObject = fea;
187

188
    // get the free edges, if set their adjacent faces and continuities
189
    auto objects = editedObject->UnboundEdges.getValues();
190
    auto edges = editedObject->UnboundEdges.getSubValues();
191
    auto count = objects.size();
192

193
    // fill up faces if wrong size
194
    auto faces = editedObject->UnboundFaces.getValues();
195
    if (faces.size() != edges.size()) {
196
        faces.resize(edges.size());
197
        std::fill(faces.begin(), faces.end(), std::string());
198
    }
199

200
    // fill up continuities if wrong size
201
    auto conts = editedObject->UnboundOrder.getValues();
202
    if (edges.size() != conts.size()) {
203
        conts.resize(edges.size());
204
        std::fill(conts.begin(), conts.end(), static_cast<long>(GeomAbs_C0));
205
    }
206

207
    App::Document* doc = editedObject->getDocument();
208
    for (std::size_t i = 0; i < count; i++) {
209
        App::DocumentObject* obj = objects[i];
210
        std::string edge = edges[i];
211
        std::string face = faces[i];
212

213
        QListWidgetItem* item = new QListWidgetItem(ui->listUnbound);
214
        ui->listUnbound->addItem(item);
215

216
        QString text = QString::fromLatin1("%1.%2").arg(QString::fromUtf8(obj->Label.getValue()),
217
                                                        QString::fromStdString(edge));
218
        item->setText(text);
219

220
        // The user data field of a list widget item
221
        // is a list of five elementa:
222
        // 1. document name
223
        // 2. object name
224
        // 3. sub-element name of the edge
225
        // 4. sub-element of an adjacent face or empty string
226
        // 5. the continuity as int
227
        QList<QVariant> data;
228
        data << QByteArray(doc->getName());
229
        data << QByteArray(obj->getNameInDocument());
230
        data << QByteArray(edge.c_str());
231
        data << QByteArray(face.c_str());
232
        data << static_cast<int>(conts[i]);
233
        item->setData(Qt::UserRole, data);
234
    }
235

236
    // attach this document observer
237
    attachDocument(Gui::Application::Instance->getDocument(doc));
238
}
239

240
void FillingEdgePanel::changeEvent(QEvent* e)
241
{
242
    if (e->type() == QEvent::LanguageChange) {
243
        ui->retranslateUi(this);
244
    }
245
    else {
246
        QWidget::changeEvent(e);
247
    }
248
}
249

250
void FillingEdgePanel::open()
251
{
252
    checkOpenCommand();
253

254
    // highlight the boundary edges
255
    this->vp->highlightReferences(ViewProviderFilling::Edge,
256
                                  editedObject->UnboundEdges.getSubListValues(),
257
                                  true);
258

259
    Gui::Selection().clearSelection();
260
}
261

262
void FillingEdgePanel::clearSelection()
263
{
264
    Gui::Selection().clearSelection();
265
}
266

267
void FillingEdgePanel::checkOpenCommand()
268
{
269
    if (checkCommand && !Gui::Command::hasPendingCommand()) {
270
        std::string Msg("Edit ");
271
        Msg += editedObject->Label.getValue();
272
        Gui::Command::openCommand(Msg.c_str());
273
        checkCommand = false;
274
    }
275
}
276

277
void FillingEdgePanel::slotUndoDocument(const Gui::Document&)
278
{
279
    checkCommand = true;
280
}
281

282
void FillingEdgePanel::slotRedoDocument(const Gui::Document&)
283
{
284
    checkCommand = true;
285
}
286

287
void FillingEdgePanel::slotDeletedObject(const Gui::ViewProviderDocumentObject& Obj)
288
{
289
    // If this view provider is being deleted then reset the colors of
290
    // referenced part objects. The dialog will be deleted later.
291
    if (this->vp == &Obj) {
292
        this->vp->highlightReferences(ViewProviderFilling::Edge,
293
                                      editedObject->UnboundEdges.getSubListValues(),
294
                                      false);
295
    }
296
}
297

298
bool FillingEdgePanel::accept()
299
{
300
    selectionMode = None;
301
    Gui::Selection().rmvSelectionGate();
302

303
    if (editedObject->mustExecute()) {
304
        editedObject->recomputeFeature();
305
    }
306
    if (!editedObject->isValid()) {
307
        QMessageBox::warning(this,
308
                             tr("Invalid object"),
309
                             QString::fromLatin1(editedObject->getStatusString()));
310
        return false;
311
    }
312

313
    this->vp->highlightReferences(ViewProviderFilling::Edge,
314
                                  editedObject->UnboundEdges.getSubListValues(),
315
                                  false);
316
    return true;
317
}
318

319
bool FillingEdgePanel::reject()
320
{
321
    this->vp->highlightReferences(ViewProviderFilling::Edge,
322
                                  editedObject->UnboundEdges.getSubListValues(),
323
                                  false);
324

325
    selectionMode = None;
326
    Gui::Selection().rmvSelectionGate();
327

328
    return true;
329
}
330

331
void FillingEdgePanel::onButtonUnboundEdgeAddToggled(bool checked)
332
{
333
    if (checked) {
334
        // 'selectionMode' is passed by reference and changed when the filter is deleted
335
        Gui::Selection().addSelectionGate(new ShapeSelection(selectionMode, editedObject));
336
        selectionMode = AppendEdge;
337
    }
338
    else if (selectionMode == AppendEdge) {
339
        exitSelectionMode();
340
    }
341
}
342

343
void FillingEdgePanel::onButtonUnboundEdgeRemoveToggled(bool checked)
344
{
345
    if (checked) {
346
        // 'selectionMode' is passed by reference and changed when the filter is deleted
347
        Gui::Selection().addSelectionGate(new ShapeSelection(selectionMode, editedObject));
348
        selectionMode = RemoveEdge;
349
    }
350
    else if (selectionMode == RemoveEdge) {
351
        exitSelectionMode();
352
    }
353
}
354

355
void FillingEdgePanel::onListUnboundItemDoubleClicked(QListWidgetItem* item)
356
{
357
    Gui::Selection().clearSelection();
358
    Gui::Selection().rmvSelectionGate();
359
    selectionMode = None;
360

361
    ui->comboBoxUnboundFaces->clear();
362
    ui->comboBoxUnboundCont->clear();
363

364
    if (item) {
365
        QList<QVariant> data;
366
        data = item->data(Qt::UserRole).toList();
367

368
        try {
369
            App::Document* doc = App::GetApplication().getDocument(data[0].toByteArray());
370
            App::DocumentObject* obj = doc ? doc->getObject(data[1].toByteArray()) : nullptr;
371
            if (obj && obj->isDerivedFrom<Part::Feature>()) {
372
                const Part::TopoShape& shape = static_cast<Part::Feature*>(obj)->Shape.getShape();
373
                TopoDS_Shape edge = shape.getSubShape(data[2].toByteArray());
374

375
                // build up map edge->face
376
                TopTools_IndexedMapOfShape faces;
377
                TopExp::MapShapes(shape.getShape(), TopAbs_FACE, faces);
378
                TopTools_IndexedDataMapOfShapeListOfShape edge2Face;
379
                TopExp::MapShapesAndAncestors(shape.getShape(),
380
                                              TopAbs_EDGE,
381
                                              TopAbs_FACE,
382
                                              edge2Face);
383
                const TopTools_ListOfShape& adj_faces = edge2Face.FindFromKey(edge);
384
                if (adj_faces.Extent() > 0) {
385
                    int n = adj_faces.Extent();
386
                    ui->statusLabel->setText(tr("Edge has %n adjacent face(s)", nullptr, n));
387

388
                    // fill up the combo boxes
389
                    modifyBoundary(true);
390
                    ui->comboBoxUnboundFaces->addItem(tr("None"), QByteArray(""));
391
                    ui->comboBoxUnboundCont->addItem(QString::fromLatin1("C0"),
392
                                                     static_cast<int>(GeomAbs_C0));
393
                    ui->comboBoxUnboundCont->addItem(QString::fromLatin1("G1"),
394
                                                     static_cast<int>(GeomAbs_G1));
395
                    ui->comboBoxUnboundCont->addItem(QString::fromLatin1("G2"),
396
                                                     static_cast<int>(GeomAbs_G2));
397
                    TopTools_ListIteratorOfListOfShape it(adj_faces);
398
                    for (; it.More(); it.Next()) {
399
                        const TopoDS_Shape& F = it.Value();
400
                        int index = faces.FindIndex(F);
401
                        QString text = QString::fromLatin1("Face%1").arg(index);
402
                        ui->comboBoxUnboundFaces->addItem(text, text.toLatin1());
403
                    }
404

405
                    // activate face and continuity
406
                    if (data.size() == 5) {
407
                        int index = ui->comboBoxUnboundFaces->findData(data[3]);
408
                        ui->comboBoxUnboundFaces->setCurrentIndex(index);
409
                        index = ui->comboBoxUnboundCont->findData(data[4]);
410
                        ui->comboBoxUnboundCont->setCurrentIndex(index);
411
                    }
412
                }
413
                else {
414
                    ui->statusLabel->setText(tr("Edge has no adjacent faces"));
415
                }
416
            }
417

418
            Gui::Selection().addSelection(data[0].toByteArray(),
419
                                          data[1].toByteArray(),
420
                                          data[2].toByteArray());
421
        }
422
        catch (...) {
423
        }
424
    }
425
}
426

427
void FillingEdgePanel::onSelectionChanged(const Gui::SelectionChanges& msg)
428
{
429
    if (selectionMode == None) {
430
        return;
431
    }
432

433
    if (msg.Type == Gui::SelectionChanges::AddSelection) {
434
        checkOpenCommand();
435
        if (selectionMode == AppendEdge) {
436
            QListWidgetItem* item = new QListWidgetItem(ui->listUnbound);
437
            ui->listUnbound->addItem(item);
438

439
            Gui::SelectionObject sel(msg);
440
            QString text = QString::fromLatin1("%1.%2").arg(
441
                QString::fromUtf8(sel.getObject()->Label.getValue()),
442
                QString::fromLatin1(msg.pSubName));
443
            item->setText(text);
444

445
            QList<QVariant> data;
446
            data << QByteArray(msg.pDocName);
447
            data << QByteArray(msg.pObjectName);
448
            data << QByteArray(msg.pSubName);
449
            data << QByteArray("");
450
            data << static_cast<int>(GeomAbs_C0);
451
            item->setData(Qt::UserRole, data);
452

453
            auto objects = editedObject->UnboundEdges.getValues();
454
            std::size_t count = objects.size();
455
            objects.push_back(sel.getObject());
456
            auto element = editedObject->UnboundEdges.getSubValues();
457
            element.emplace_back(msg.pSubName);
458
            editedObject->UnboundEdges.setValues(objects, element);
459

460
            // extend faces and continuities lists if needed
461
            auto faces = editedObject->UnboundFaces.getValues();
462
            if (count == faces.size()) {
463
                faces.emplace_back();
464
                editedObject->UnboundFaces.setValues(faces);
465
            }
466
            auto conts = editedObject->UnboundOrder.getValues();
467
            if (count == conts.size()) {
468
                conts.push_back(static_cast<long>(GeomAbs_C0));
469
                editedObject->UnboundOrder.setValues(conts);
470
            }
471

472
            this->vp->highlightReferences(ViewProviderFilling::Edge,
473
                                          editedObject->UnboundEdges.getSubListValues(),
474
                                          true);
475
        }
476
        else if (selectionMode == RemoveEdge) {
477
            Gui::SelectionObject sel(msg);
478
            QList<QVariant> data;
479
            data << QByteArray(msg.pDocName);
480
            data << QByteArray(msg.pObjectName);
481
            data << QByteArray(msg.pSubName);
482

483
            // only the three first elements must match
484
            for (int i = 0; i < ui->listUnbound->count(); i++) {
485
                QListWidgetItem* item = ui->listUnbound->item(i);
486
                QList<QVariant> userdata = item->data(Qt::UserRole).toList();
487
                if (userdata.mid(0, 3) == data) {
488
                    ui->listUnbound->takeItem(i);
489
                    delete item;
490
                    break;
491
                }
492
            }
493

494
            this->vp->highlightReferences(ViewProviderFilling::Edge,
495
                                          editedObject->UnboundEdges.getSubListValues(),
496
                                          false);
497
            App::DocumentObject* obj = sel.getObject();
498
            std::string sub = msg.pSubName;
499
            auto objects = editedObject->UnboundEdges.getValues();
500
            auto element = editedObject->UnboundEdges.getSubValues();
501
            auto it = objects.begin();
502
            auto jt = element.begin();
503

504
            for (; it != objects.end() && jt != element.end(); ++it, ++jt) {
505
                if (*it == obj && *jt == sub) {
506
                    std::size_t index = std::distance(objects.begin(), it);
507

508
                    objects.erase(it);
509
                    element.erase(jt);
510
                    editedObject->UnboundEdges.setValues(objects, element);
511

512
                    // try to remove the item also from the faces
513
                    auto faces = editedObject->UnboundFaces.getValues();
514
                    if (index < faces.size()) {
515
                        faces.erase(faces.begin() + index);
516
                        editedObject->UnboundFaces.setValues(faces);
517
                    }
518

519
                    // try to remove the item also from the orders
520
                    auto order = editedObject->UnboundOrder.getValues();
521
                    if (index < order.size()) {
522
                        order.erase(order.begin() + index);
523
                        editedObject->UnboundOrder.setValues(order);
524
                    }
525
                    break;
526
                }
527
            }
528
            this->vp->highlightReferences(ViewProviderFilling::Edge,
529
                                          editedObject->UnboundEdges.getSubListValues(),
530
                                          true);
531
        }
532

533
        editedObject->recomputeFeature();
534
        QTimer::singleShot(50, this, &FillingEdgePanel::clearSelection);
535
    }
536
}
537

538
void FillingEdgePanel::onDeleteUnboundEdge()
539
{
540
    int row = ui->listUnbound->currentRow();
541
    QListWidgetItem* item = ui->listUnbound->item(row);
542
    if (item) {
543
        checkOpenCommand();
544
        QList<QVariant> data;
545
        data = item->data(Qt::UserRole).toList();
546
        ui->listUnbound->takeItem(row);
547
        delete item;
548

549
        App::Document* doc = App::GetApplication().getDocument(data[0].toByteArray());
550
        App::DocumentObject* obj = doc ? doc->getObject(data[1].toByteArray()) : nullptr;
551
        std::string sub = data[2].toByteArray().constData();
552
        auto objects = editedObject->UnboundEdges.getValues();
553
        auto element = editedObject->UnboundEdges.getSubValues();
554
        auto it = objects.begin();
555
        auto jt = element.begin();
556
        this->vp->highlightReferences(ViewProviderFilling::Edge,
557
                                      editedObject->UnboundEdges.getSubListValues(),
558
                                      false);
559
        for (; it != objects.end() && jt != element.end(); ++it, ++jt) {
560
            if (*it == obj && *jt == sub) {
561
                std::size_t index = std::distance(objects.begin(), it);
562

563
                objects.erase(it);
564
                element.erase(jt);
565
                editedObject->UnboundEdges.setValues(objects, element);
566

567
                // try to remove the item also from the faces
568
                auto faces = editedObject->UnboundFaces.getValues();
569
                if (index < faces.size()) {
570
                    faces.erase(faces.begin() + index);
571
                    editedObject->UnboundFaces.setValues(faces);
572
                }
573

574
                // try to remove the item also from the orders
575
                auto order = editedObject->UnboundOrder.getValues();
576
                if (index < order.size()) {
577
                    order.erase(order.begin() + index);
578
                    editedObject->UnboundOrder.setValues(order);
579
                }
580
                break;
581
            }
582
        }
583
        this->vp->highlightReferences(ViewProviderFilling::Edge,
584
                                      editedObject->UnboundEdges.getSubListValues(),
585
                                      true);
586

587
        editedObject->recomputeFeature();
588
    }
589
}
590

591
void FillingEdgePanel::onButtonUnboundAcceptClicked()
592
{
593
    QListWidgetItem* item = ui->listUnbound->currentItem();
594
    if (item) {
595
        QList<QVariant> data;
596
        data = item->data(Qt::UserRole).toList();
597

598
        QVariant face =
599
            ui->comboBoxUnboundFaces->itemData(ui->comboBoxUnboundFaces->currentIndex());
600
        QVariant cont = ui->comboBoxUnboundCont->itemData(ui->comboBoxUnboundCont->currentIndex());
601
        if (data.size() == 5) {
602
            data[3] = face;
603
            data[4] = cont;
604
        }
605
        else {
606
            data << face;
607
            data << cont;
608
        }
609

610
        item->setData(Qt::UserRole, data);
611

612
        std::size_t index = ui->listUnbound->row(item);
613

614
        // try to set the item of the faces
615
        auto faces = editedObject->UnboundFaces.getValues();
616
        if (index < faces.size()) {
617
            faces[index] = face.toByteArray().data();
618
            editedObject->UnboundFaces.setValues(faces);
619
        }
620

621
        // try to set the item of the orders
622
        auto order = editedObject->UnboundOrder.getValues();
623
        if (index < order.size()) {
624
            order[index] = cont.toInt();
625
            editedObject->UnboundOrder.setValues(order);
626
        }
627
    }
628

629
    modifyBoundary(false);
630
    ui->comboBoxUnboundFaces->clear();
631
    ui->comboBoxUnboundCont->clear();
632
    ui->statusLabel->clear();
633

634
    editedObject->recomputeFeature();
635
}
636

637
void FillingEdgePanel::onButtonUnboundIgnoreClicked()
638
{
639
    modifyBoundary(false);
640
    ui->comboBoxUnboundFaces->clear();
641
    ui->comboBoxUnboundCont->clear();
642
    ui->statusLabel->clear();
643
}
644

645
void FillingEdgePanel::modifyBoundary(bool on)
646
{
647
    ui->buttonUnboundEdgeAdd->setDisabled(on);
648
    ui->buttonUnboundEdgeRemove->setDisabled(on);
649
    ui->listUnbound->setDisabled(on);
650

651
    ui->comboBoxUnboundFaces->setEnabled(on);
652
    ui->comboBoxUnboundCont->setEnabled(on);
653
    ui->buttonUnboundAccept->setEnabled(on);
654
    ui->buttonUnboundIgnore->setEnabled(on);
655
}
656
}  // namespace SurfaceGui
657

658
void FillingEdgePanel::exitSelectionMode()
659
{
660
    // 'selectionMode' is passed by reference to the filter and changed when the filter is deleted
661
    Gui::Selection().clearSelection();
662
    Gui::Selection().rmvSelectionGate();
663
}
664

665
#include "moc_TaskFillingEdge.cpp"
666

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.