FreeCAD

Форк
0
/
TaskLoft.cpp 
276 строк · 9.4 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2011 Werner Mayer <wmayer[at]users.sourceforge.net>     *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
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.      *
10
 *                                                                         *
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.                  *
15
 *                                                                         *
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                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24

25
#ifndef _PreComp_
26
# include <QMessageBox>
27
# include <QTextStream>
28
# include <QTreeWidget>
29
# include <Precision.hxx>
30
# include <ShapeAnalysis_FreeBounds.hxx>
31
# include <TopoDS.hxx>
32
# include <TopoDS_Iterator.hxx>
33
# include <TopTools_HSequenceOfShape.hxx>
34
#endif
35

36
#include <App/Application.h>
37
#include <App/Document.h>
38
#include <App/DocumentObject.h>
39
#include <Gui/Application.h>
40
#include <Gui/BitmapFactory.h>
41
#include <Gui/Command.h>
42
#include <Gui/Document.h>
43
#include <Gui/Selection.h>
44
#include <Gui/ViewProvider.h>
45

46
#include <Mod/Part/App/PartFeature.h>
47

48
#include "TaskLoft.h"
49
#include "ui_TaskLoft.h"
50

51

52
using namespace PartGui;
53

54
class LoftWidget::Private
55
{
56
public:
57
    Ui_TaskLoft ui;
58
    std::string document;
59
    Private() = default;
60
    ~Private() = default;
61
};
62

63
/* TRANSLATOR PartGui::LoftWidget */
64

65
LoftWidget::LoftWidget(QWidget* parent)
66
  : d(new Private())
67
{
68
    Q_UNUSED(parent);
69
    Gui::Command::runCommand(Gui::Command::App, "from FreeCAD import Base");
70
    Gui::Command::runCommand(Gui::Command::App, "import Part");
71

72
    d->ui.setupUi(this);
73
    d->ui.selector->setAvailableLabel(tr("Available profiles"));
74
    d->ui.selector->setSelectedLabel(tr("Selected profiles"));
75

76
    // clang-format off
77
    connect(d->ui.selector->availableTreeWidget(), &QTreeWidget::currentItemChanged,
78
            this, &LoftWidget::onCurrentItemChanged);
79
    connect(d->ui.selector->selectedTreeWidget(), &QTreeWidget::currentItemChanged,
80
            this, &LoftWidget::onCurrentItemChanged);
81
    // clang-format on
82

83
    findShapes();
84
}
85

86
LoftWidget::~LoftWidget()
87
{
88
    delete d;
89
}
90

91
void LoftWidget::findShapes()
92
{
93
    App::Document* activeDoc = App::GetApplication().getActiveDocument();
94
    Gui::Document* activeGui = Gui::Application::Instance->getDocument(activeDoc);
95
    if (!activeGui)
96
        return;
97
    d->document = activeDoc->getName();
98

99
    std::vector<App::DocumentObject*> objs = activeDoc->getObjectsOfType<App::DocumentObject>();
100

101
    for (auto obj : objs) {
102
        Part::TopoShape topoShape = Part::Feature::getTopoShape(obj);
103
        if (topoShape.isNull()) {
104
            continue;
105
        }
106
        TopoDS_Shape shape = topoShape.getShape();
107
        if (shape.IsNull()) continue;
108

109
        // also allow compounds with a single face, wire or vertex or
110
        // if there are only edges building one wire
111
        if (shape.ShapeType() == TopAbs_COMPOUND) {
112
            Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape();
113
            Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape();
114

115
            TopoDS_Iterator it(shape);
116
            int numChilds=0;
117
            TopoDS_Shape child;
118
            for (; it.More(); it.Next(), numChilds++) {
119
                if (!it.Value().IsNull()) {
120
                    child = it.Value();
121
                    if (child.ShapeType() == TopAbs_EDGE) {
122
                        hEdges->Append(child);
123
                    }
124
                }
125
            }
126

127
            // a single child
128
            if (numChilds == 1) {
129
                shape = child;
130
            }
131
            // or all children are edges
132
            else if (hEdges->Length() == numChilds) {
133
                ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges,
134
                    Precision::Confusion(), Standard_False, hWires);
135
                if (hWires->Length() == 1)
136
                    shape = hWires->Value(1);
137
            }
138
        }
139

140
        if (shape.ShapeType() == TopAbs_FACE ||
141
            shape.ShapeType() == TopAbs_WIRE ||
142
            shape.ShapeType() == TopAbs_EDGE ||
143
            shape.ShapeType() == TopAbs_VERTEX) {
144
            QString label = QString::fromUtf8(obj->Label.getValue());
145
            QString name = QString::fromLatin1(obj->getNameInDocument());
146
            QTreeWidgetItem* child = new QTreeWidgetItem();
147
            child->setText(0, label);
148
            child->setToolTip(0, label);
149
            child->setData(0, Qt::UserRole, name);
150
            Gui::ViewProvider* vp = activeGui->getViewProvider(obj);
151
            if (vp) child->setIcon(0, vp->getIcon());
152
            d->ui.selector->availableTreeWidget()->addTopLevelItem(child);
153
        }
154
    }
155
}
156

157
bool LoftWidget::accept()
158
{
159
    QString list, solid, ruled, closed;
160
    if (d->ui.checkSolid->isChecked())
161
        solid = QString::fromLatin1("True");
162
    else
163
        solid = QString::fromLatin1("False");
164

165
    if (d->ui.checkRuledSurface->isChecked())
166
        ruled = QString::fromLatin1("True");
167
    else
168
        ruled = QString::fromLatin1("False");
169

170
    if (d->ui.checkClosed->isChecked())
171
        closed = QString::fromLatin1("True");
172
    else
173
        closed = QString::fromLatin1("False");
174

175
    QTextStream str(&list);
176

177
    int count = d->ui.selector->selectedTreeWidget()->topLevelItemCount();
178
    if (count < 2) {
179
        QMessageBox::critical(this, tr("Too few elements"), tr("At least two vertices, edges, wires or faces are required."));
180
        return false;
181
    }
182
    for (int i=0; i<count; i++) {
183
        QTreeWidgetItem* child = d->ui.selector->selectedTreeWidget()->topLevelItem(i);
184
        QString name = child->data(0, Qt::UserRole).toString();
185
        str << "App.getDocument('" << d->document.c_str() << "')." << name << ", ";
186
    }
187

188
    try {
189
        QString cmd;
190
        cmd = QString::fromLatin1(
191
            "App.getDocument('%5').addObject('Part::Loft','Loft')\n"
192
            "App.getDocument('%5').ActiveObject.Sections=[%1]\n"
193
            "App.getDocument('%5').ActiveObject.Solid=%2\n"
194
            "App.getDocument('%5').ActiveObject.Ruled=%3\n"
195
            "App.getDocument('%5').ActiveObject.Closed=%4\n"
196
            ).arg(list, solid, ruled, closed, QString::fromLatin1(d->document.c_str()));
197

198
        Gui::Document* doc = Gui::Application::Instance->getDocument(d->document.c_str());
199
        if (!doc)
200
            throw Base::RuntimeError("Document doesn't exist anymore");
201
        doc->openCommand(QT_TRANSLATE_NOOP("Command", "Loft"));
202
        Gui::Command::runCommand(Gui::Command::App, cmd.toLatin1());
203
        doc->getDocument()->recompute();
204
        App::DocumentObject* obj = doc->getDocument()->getActiveObject();
205
        if (obj && !obj->isValid()) {
206
            std::string msg = obj->getStatusString();
207
            doc->abortCommand();
208
            throw Base::RuntimeError(msg);
209
        }
210
        doc->commitCommand();
211
    }
212
    catch (const Base::Exception& e) {
213
        QMessageBox::warning(this, tr("Input error"), QCoreApplication::translate("Exception", e.what()));
214
        return false;
215
    }
216

217
    return true;
218
}
219

220
bool LoftWidget::reject()
221
{
222
    return true;
223
}
224

225
void LoftWidget::onCurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous)
226
{
227
    if (previous) {
228
        Gui::Selection().rmvSelection(d->document.c_str(),
229
            (const char*)previous->data(0,Qt::UserRole).toByteArray());
230
    }
231
    if (current) {
232
        Gui::Selection().addSelection(d->document.c_str(),
233
            (const char*)current->data(0,Qt::UserRole).toByteArray());
234
    }
235
}
236

237
void LoftWidget::changeEvent(QEvent *e)
238
{
239
    QWidget::changeEvent(e);
240
    if (e->type() == QEvent::LanguageChange) {
241
        d->ui.retranslateUi(this);
242
        d->ui.selector->setAvailableLabel(tr("Vertex/Edge/Wire/Face"));
243
        d->ui.selector->setSelectedLabel(tr("Loft"));
244
    }
245
}
246

247

248
/* TRANSLATOR PartGui::TaskLoft */
249

250
TaskLoft::TaskLoft()
251
{
252
    widget = new LoftWidget();
253
    addTaskBox(Gui::BitmapFactory().pixmap("Part_Loft"), widget);
254
}
255

256
TaskLoft::~TaskLoft() = default;
257

258
void TaskLoft::open()
259
{
260
}
261

262
void TaskLoft::clicked(int)
263
{
264
}
265

266
bool TaskLoft::accept()
267
{
268
    return widget->accept();
269
}
270

271
bool TaskLoft::reject()
272
{
273
    return widget->reject();
274
}
275

276
#include "moc_TaskLoft.cpp"
277

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

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

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

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