1
/***************************************************************************
2
* Copyright (c) 2011 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"
26
# include <QMessageBox>
27
# include <QTextStream>
28
# include <QTreeWidget>
29
# include <Precision.hxx>
30
# include <ShapeAnalysis_FreeBounds.hxx>
32
# include <TopoDS_Iterator.hxx>
33
# include <TopTools_HSequenceOfShape.hxx>
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>
46
#include <Mod/Part/App/PartFeature.h>
49
#include "ui_TaskLoft.h"
52
using namespace PartGui;
54
class LoftWidget::Private
63
/* TRANSLATOR PartGui::LoftWidget */
65
LoftWidget::LoftWidget(QWidget* parent)
69
Gui::Command::runCommand(Gui::Command::App, "from FreeCAD import Base");
70
Gui::Command::runCommand(Gui::Command::App, "import Part");
73
d->ui.selector->setAvailableLabel(tr("Available profiles"));
74
d->ui.selector->setSelectedLabel(tr("Selected profiles"));
77
connect(d->ui.selector->availableTreeWidget(), &QTreeWidget::currentItemChanged,
78
this, &LoftWidget::onCurrentItemChanged);
79
connect(d->ui.selector->selectedTreeWidget(), &QTreeWidget::currentItemChanged,
80
this, &LoftWidget::onCurrentItemChanged);
86
LoftWidget::~LoftWidget()
91
void LoftWidget::findShapes()
93
App::Document* activeDoc = App::GetApplication().getActiveDocument();
94
Gui::Document* activeGui = Gui::Application::Instance->getDocument(activeDoc);
97
d->document = activeDoc->getName();
99
std::vector<App::DocumentObject*> objs = activeDoc->getObjectsOfType<App::DocumentObject>();
101
for (auto obj : objs) {
102
Part::TopoShape topoShape = Part::Feature::getTopoShape(obj);
103
if (topoShape.isNull()) {
106
TopoDS_Shape shape = topoShape.getShape();
107
if (shape.IsNull()) continue;
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();
115
TopoDS_Iterator it(shape);
118
for (; it.More(); it.Next(), numChilds++) {
119
if (!it.Value().IsNull()) {
121
if (child.ShapeType() == TopAbs_EDGE) {
122
hEdges->Append(child);
128
if (numChilds == 1) {
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);
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);
157
bool LoftWidget::accept()
159
QString list, solid, ruled, closed;
160
if (d->ui.checkSolid->isChecked())
161
solid = QString::fromLatin1("True");
163
solid = QString::fromLatin1("False");
165
if (d->ui.checkRuledSurface->isChecked())
166
ruled = QString::fromLatin1("True");
168
ruled = QString::fromLatin1("False");
170
if (d->ui.checkClosed->isChecked())
171
closed = QString::fromLatin1("True");
173
closed = QString::fromLatin1("False");
175
QTextStream str(&list);
177
int count = d->ui.selector->selectedTreeWidget()->topLevelItemCount();
179
QMessageBox::critical(this, tr("Too few elements"), tr("At least two vertices, edges, wires or faces are required."));
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 << ", ";
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()));
198
Gui::Document* doc = Gui::Application::Instance->getDocument(d->document.c_str());
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();
208
throw Base::RuntimeError(msg);
210
doc->commitCommand();
212
catch (const Base::Exception& e) {
213
QMessageBox::warning(this, tr("Input error"), QCoreApplication::translate("Exception", e.what()));
220
bool LoftWidget::reject()
225
void LoftWidget::onCurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous)
228
Gui::Selection().rmvSelection(d->document.c_str(),
229
(const char*)previous->data(0,Qt::UserRole).toByteArray());
232
Gui::Selection().addSelection(d->document.c_str(),
233
(const char*)current->data(0,Qt::UserRole).toByteArray());
237
void LoftWidget::changeEvent(QEvent *e)
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"));
248
/* TRANSLATOR PartGui::TaskLoft */
252
widget = new LoftWidget();
253
addTaskBox(Gui::BitmapFactory().pixmap("Part_Loft"), widget);
256
TaskLoft::~TaskLoft() = default;
262
void TaskLoft::clicked(int)
266
bool TaskLoft::accept()
268
return widget->accept();
271
bool TaskLoft::reject()
273
return widget->reject();
276
#include "moc_TaskLoft.cpp"