From 78b1282a260f501b26e4d8384f2346cba0189746 Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 14 Oct 2011 14:05:28 +0000 Subject: [PATCH] + utility to create edges, faces, shells and solids from selection +fix a couple of selection bugs in SoFCUnifiedSelection node git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5016 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Gui/Application.cpp | 11 +- src/Gui/Application.h | 2 +- src/Gui/SoFCUnifiedSelection.cpp | 16 +- src/Mod/Part/Gui/CMakeLists.txt | 7 +- src/Mod/Part/Gui/Command.cpp | 27 ++ src/Mod/Part/Gui/Makefile.am | 5 + src/Mod/Part/Gui/TaskShapeBuilder.cpp | 407 ++++++++++++++++++++++++++ src/Mod/Part/Gui/TaskShapeBuilder.h | 83 ++++++ src/Mod/Part/Gui/TaskShapeBuilder.ui | 116 ++++++++ src/Mod/Part/Gui/Workbench.cpp | 2 +- 10 files changed, 663 insertions(+), 13 deletions(-) create mode 100644 src/Mod/Part/Gui/TaskShapeBuilder.cpp create mode 100644 src/Mod/Part/Gui/TaskShapeBuilder.h create mode 100644 src/Mod/Part/Gui/TaskShapeBuilder.ui diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index 4d7e054cf6..1218c192f3 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -1251,7 +1251,7 @@ void Application::runCommand(bool bForce, const char* sCmd,...) free (format); } -bool Application::runPythonCode(const char* cmd, bool gui) +bool Application::runPythonCode(const char* cmd, bool gui, bool pyexc) { if (gui) d->macroMngr->addLine(MacroManager::Gui,cmd); @@ -1263,8 +1263,13 @@ bool Application::runPythonCode(const char* cmd, bool gui) return true; } catch (Base::PyException &e) { - e.ReportException(); - Base::Console().Error("Stack Trace: %s\n",e.getStackTrace().c_str()); + if (pyexc) { + e.ReportException(); + Base::Console().Error("Stack Trace: %s\n",e.getStackTrace().c_str()); + } + else { + throw; // re-throw to handle in calling instance + } } catch (Base::AbortException&) { } diff --git a/src/Gui/Application.h b/src/Gui/Application.h index 6f74b774d2..74b3dbb64b 100644 --- a/src/Gui/Application.h +++ b/src/Gui/Application.h @@ -177,7 +177,7 @@ public: Gui::CommandManager &commandManager(void); /// Run a Python command void runCommand(bool bForce, const char* sCmd,...); - bool runPythonCode(const char* cmd, bool gui=false); + bool runPythonCode(const char* cmd, bool gui=false, bool pyexc=true); /// helper which create the commands void createStandardOperations(); //@} diff --git a/src/Gui/SoFCUnifiedSelection.cpp b/src/Gui/SoFCUnifiedSelection.cpp index fd8ffc28db..c740a9662a 100644 --- a/src/Gui/SoFCUnifiedSelection.cpp +++ b/src/Gui/SoFCUnifiedSelection.cpp @@ -433,14 +433,14 @@ SoFCUnifiedSelection::handleEvent(SoHandleEventAction * action) type = SoSelectionElementAction::Remove; } else { - Gui::Selection().addSelection(documentName.c_str() + bool ok = Gui::Selection().addSelection(documentName.c_str() ,objectName.c_str() ,subElementName.c_str() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); - - type = SoSelectionElementAction::Append; + if (ok) + type = SoSelectionElementAction::Append; if (mymode == OFF) { snprintf(buf,512,"Selected: %s.%s.%s (%f,%f,%f)",documentName.c_str() ,objectName.c_str() @@ -458,23 +458,25 @@ SoFCUnifiedSelection::handleEvent(SoHandleEventAction * action) ,objectName.c_str() ,subElementName.c_str())) { Gui::Selection().clearSelection(documentName.c_str()); - Gui::Selection().addSelection(documentName.c_str() + bool ok = Gui::Selection().addSelection(documentName.c_str() ,objectName.c_str() ,subElementName.c_str() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); - type = SoSelectionElementAction::Append; + if (ok) + type = SoSelectionElementAction::Append; } else { Gui::Selection().clearSelection(documentName.c_str()); - Gui::Selection().addSelection(documentName.c_str() + bool ok = Gui::Selection().addSelection(documentName.c_str() ,objectName.c_str() ,0 ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); - type = SoSelectionElementAction::All; + if (ok) + type = SoSelectionElementAction::All; } if (mymode == OFF) { diff --git a/src/Mod/Part/Gui/CMakeLists.txt b/src/Mod/Part/Gui/CMakeLists.txt index 93da9734fd..e740c63069 100644 --- a/src/Mod/Part/Gui/CMakeLists.txt +++ b/src/Mod/Part/Gui/CMakeLists.txt @@ -39,6 +39,7 @@ set(PartGui_MOC_HDRS DlgSettings3DViewPartImp.h DlgSettingsGeneral.h TaskFaceColors.h + TaskShapeBuilder.h ) fc_wrap_cpp(PartGui_MOC_SRCS ${PartGui_MOC_HDRS}) SOURCE_GROUP("Moc" FILES ${PartGui_MOC_SRCS}) @@ -60,6 +61,7 @@ set(PartGui_UIC_SRCS DlgSettings3DViewPart.ui DlgSettingsGeneral.ui TaskFaceColors.ui + TaskShapeBuilder.ui ) qt4_wrap_ui(PartGui_UIC_HDRS ${PartGui_UIC_SRCS}) @@ -143,11 +145,14 @@ SET(PartGui_SRCS TaskFaceColors.cpp TaskFaceColors.h TaskFaceColors.ui + TaskShapeBuilder.cpp + TaskShapeBuilder.h + TaskShapeBuilder.ui ) SET(PartGui_Scripts InitGui.py - TestPartGui.py + TestPartGui.py ) diff --git a/src/Mod/Part/Gui/Command.cpp b/src/Mod/Part/Gui/Command.cpp index 50cbe26652..a4b31f52a5 100644 --- a/src/Mod/Part/Gui/Command.cpp +++ b/src/Mod/Part/Gui/Command.cpp @@ -57,6 +57,7 @@ #include "CrossSections.h" #include "Mirroring.h" #include "ViewProvider.h" +#include "TaskShapeBuilder.h" //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -877,6 +878,31 @@ bool CmdPartCrossSections::isActive(void) //-------------------------------------------------------------------------------------- +DEF_STD_CMD_A(CmdPartBuilder); + +CmdPartBuilder::CmdPartBuilder() + :Command("Part_Builder") +{ + sAppModule = "Part"; + sGroup = QT_TR_NOOP("Part"); + sMenuText = QT_TR_NOOP("Shape builder..."); + sToolTipText = QT_TR_NOOP("Advanced utility to create shapes"); + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; +} + +void CmdPartBuilder::activated(int iMsg) +{ + Gui::Control().showDialog(new PartGui::TaskShapeBuilder()); +} + +bool CmdPartBuilder::isActive(void) +{ + return (hasActiveDocument() && !Gui::Control().activeDialog()); +} + +//-------------------------------------------------------------------------------------- + DEF_STD_CMD_A(CmdShapeInfo); CmdShapeInfo::CmdShapeInfo() @@ -1106,5 +1132,6 @@ void CreatePartCommands(void) rcCmdMgr.addCommand(new CmdPartPickCurveNet()); rcCmdMgr.addCommand(new CmdShapeInfo()); rcCmdMgr.addCommand(new CmdPartRuledSurface()); + rcCmdMgr.addCommand(new CmdPartBuilder()); } diff --git a/src/Mod/Part/Gui/Makefile.am b/src/Mod/Part/Gui/Makefile.am index b68c31dfae..53121a5317 100644 --- a/src/Mod/Part/Gui/Makefile.am +++ b/src/Mod/Part/Gui/Makefile.am @@ -16,6 +16,7 @@ BUILT_SOURCES=\ ui_DlgSettingsGeneral.h \ ui_Mirroring.h \ ui_TaskFaceColors.h \ + ui_TaskShapeBuilder.h \ moc_CrossSections.cpp \ moc_DlgBooleanOperation.cpp \ moc_DlgExtrusion.cpp \ @@ -30,6 +31,7 @@ BUILT_SOURCES=\ moc_DlgSettingsGeneral.cpp \ moc_Mirroring.cpp \ moc_TaskFaceColors.cpp \ + moc_TaskShapeBuilder.cpp \ qrc_Part.cpp libPartGui_la_SOURCES=\ @@ -64,6 +66,8 @@ libPartGui_la_SOURCES=\ Mirroring.h \ TaskFaceColors.cpp \ TaskFaceColors.h \ + TaskShapeBuilder.cpp \ + TaskShapeBuilder.h \ PreCompiled.cpp \ PreCompiled.h \ SoBrepShape.cpp \ @@ -210,6 +214,7 @@ EXTRA_DIST = \ DlgSettingsGeneral.ui \ Mirroring.ui \ TaskFaceColors.ui \ + TaskShapeBuilder.ui \ Resources/Part.qrc \ Resources/translations/Part_af.qm \ Resources/translations/Part_af.ts \ diff --git a/src/Mod/Part/Gui/TaskShapeBuilder.cpp b/src/Mod/Part/Gui/TaskShapeBuilder.cpp new file mode 100644 index 0000000000..cd9ce5a930 --- /dev/null +++ b/src/Mod/Part/Gui/TaskShapeBuilder.cpp @@ -0,0 +1,407 @@ +/*************************************************************************** + * Copyright (c) 2011 Werner Mayer * + * * + * 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 +# include +# include +# include +# include +#endif + +#include "ui_TaskShapeBuilder.h" +#include "TaskShapeBuilder.h" +#include "ViewProviderExt.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +using namespace PartGui; + +namespace PartGui { + class ShapeSelection : public Gui::SelectionFilterGate + { + public: + enum Type {VERTEX, EDGE, FACE, ALL}; + Type mode; + ShapeSelection() + : Gui::SelectionFilterGate((Gui::SelectionFilter*)0), mode(ALL) + { + } + void setMode(Type mode) + { + this->mode = mode; + } + bool allow(App::Document*, App::DocumentObject*, const char*sSubName) + { + if (!sSubName || sSubName[0] == '\0') + return (mode == ALL); + std::string element(sSubName); + switch (mode) { + case VERTEX: + return element.substr(0,6) == "Vertex"; + case EDGE: + return element.substr(0,4) == "Edge"; + case FACE: + return element.substr(0,4) == "Face"; + default: + return true; + } + } + }; +} + +class ShapeBuilderWidget::Private +{ +public: + Ui_TaskShapeBuilder ui; + QButtonGroup bg; + ShapeSelection* gate; + Private() + { + } + ~Private() + { + } +}; + +/* TRANSLATOR PartGui::TaskShapeBuilder */ + +ShapeBuilderWidget::ShapeBuilderWidget(QWidget* parent) + : d(new Private()) +{ + Gui::Application::Instance->runPythonCode("from FreeCAD import Base"); + Gui::Application::Instance->runPythonCode("import Part"); + + d->ui.setupUi(this); + d->ui.label->setText(QString()); + d->bg.addButton(d->ui.radioButtonEdge, 0); + d->bg.addButton(d->ui.radioButtonFace, 1); + d->bg.addButton(d->ui.radioButtonShell, 2); + d->bg.addButton(d->ui.radioButtonSolid, 3); + d->bg.setExclusive(true); + + connect(&d->bg, SIGNAL(buttonClicked(int)), + this, SLOT(switchMode(int))); + + d->gate = new ShapeSelection(); + Gui::Selection().addSelectionGate(d->gate); + + d->bg.button(0)->setChecked(true); + switchMode(0); +} + +ShapeBuilderWidget::~ShapeBuilderWidget() +{ + Gui::Selection().rmvSelectionGate(); + delete d; +} + +void ShapeBuilderWidget::on_createButton_clicked() +{ + int mode = d->bg.checkedId(); + Gui::Document* doc = Gui::Application::Instance->activeDocument(); + if (!doc) return; + + try { + if (mode == 0) { + createEdge(); + } + else if (mode == 1) { + createFace(); + } + else if (mode == 2) { + createShell(); + } + else if (mode == 3) { + createSolid(); + } + doc->getDocument()->recompute(); + } + catch (const Base::Exception& e) { + Base::Console().Error("%s\n", e.what()); + } +} + +void ShapeBuilderWidget::createEdge() +{ + Gui::SelectionFilter vertexFilter ("SELECT Part::Feature SUBELEMENT Vertex COUNT 2"); + bool matchVertex = vertexFilter.match(); + if (!matchVertex) { + QMessageBox::critical(this, tr("Wrong selection"), tr("Select two vertices")); + return; + } + + std::vector sel = vertexFilter.Result[0]; + std::vector elements; + std::vector::iterator it; + std::vector::const_iterator jt; + for (it=sel.begin();it!=sel.end();++it) { + for (jt=it->getSubNames().begin();jt!=it->getSubNames().end();++jt) { + QString line; + QTextStream str(&line); + str << "App.ActiveDocument." << it->getFeatName() << ".Shape." << jt->c_str() << ".Point"; + elements.push_back(line); + } + } + + // should actually never happen + if (elements.size() != 2) { + QMessageBox::critical(this, tr("Wrong selection"), tr("Select two vertices")); + return; + } + + QString cmd; + cmd = QString::fromAscii( + "_=Part.makeLine(%1, %2)\n" + "if _.isNull(): raise Exception('Failed to create edge')\n" + "App.ActiveDocument.addObject('Part::Feature','Edge').Shape=_\n" + "del _\n" + ).arg(elements[0]).arg(elements[1]); + + Gui::Application::Instance->activeDocument()->openCommand("Edge"); + Gui::Application::Instance->runPythonCode((const char*)cmd.toAscii(), false, false); + Gui::Application::Instance->activeDocument()->commitCommand(); +} + +void ShapeBuilderWidget::createFace() +{ + Gui::SelectionFilter edgeFilter ("SELECT Part::Feature SUBELEMENT Edge COUNT 3.."); + bool matchEdge = edgeFilter.match(); + if (!matchEdge) { + QMessageBox::critical(this, tr("Wrong selection"), tr("Select three or more edges")); + return; + } + + std::vector sel = edgeFilter.Result[0]; + std::vector::iterator it; + std::vector::const_iterator jt; + + QString list; + QTextStream str(&list); + str << "["; + for (it=sel.begin();it!=sel.end();++it) { + for (jt=it->getSubNames().begin();jt!=it->getSubNames().end();++jt) { + str << "App.ActiveDocument." << it->getFeatName() << ".Shape." << jt->c_str() << ", "; + } + } + str << "]"; + + QString cmd; + if (d->ui.checkPlanar->isChecked()) { + cmd = QString::fromAscii( + "_=Part.Face(Part.Wire(Part.__sortEdges__(%1)))\n" + "if _.isNull(): raise Exception('Failed to create face')\n" + "App.ActiveDocument.addObject('Part::Feature','Face').Shape=_\n" + "del _\n" + ).arg(list); + } + else { + cmd = QString::fromAscii( + "_=Part.makeFilledFace(Part.__sortEdges__(%1))\n" + "if _.isNull(): raise Exception('Failed to create face')\n" + "App.ActiveDocument.addObject('Part::Feature','Face').Shape=_\n" + "del _\n" + ).arg(list); + } + + Gui::Application::Instance->activeDocument()->openCommand("Face"); + Gui::Application::Instance->runPythonCode((const char*)cmd.toAscii(), false, false); + Gui::Application::Instance->activeDocument()->commitCommand(); +} + +void ShapeBuilderWidget::createShell() +{ + Gui::SelectionFilter faceFilter ("SELECT Part::Feature SUBELEMENT Face COUNT 2.."); + bool matchFace = faceFilter.match(); + if (!matchFace) { + QMessageBox::critical(this, tr("Wrong selection"), tr("Select two or more faces")); + return; + } + + std::vector sel = faceFilter.Result[0]; + std::vector::iterator it; + std::vector::const_iterator jt; + + QString list; + QTextStream str(&list); + if (d->ui.checkFaces->isChecked()) { + std::set obj; + for (it=sel.begin();it!=sel.end();++it) + obj.insert(it->getObject()); + str << "[]"; + for (std::set::iterator it = obj.begin(); it != obj.end(); ++it) { + str << "+ App.ActiveDocument." << (*it)->getNameInDocument() << ".Shape.Faces"; + } + } + else { + str << "["; + for (it=sel.begin();it!=sel.end();++it) { + for (jt=it->getSubNames().begin();jt!=it->getSubNames().end();++jt) { + str << "App.ActiveDocument." << it->getFeatName() << ".Shape." << jt->c_str() << ", "; + } + } + str << "]"; + } + + QString cmd; + cmd = QString::fromAscii( + "_=Part.Shell(%1)\n" + "if _.isNull(): raise Exception('Failed to create shell')\n" + "App.ActiveDocument.addObject('Part::Feature','Shell').Shape=_\n" + "del _\n" + ).arg(list); + + Gui::Application::Instance->activeDocument()->openCommand("Shell"); + Gui::Application::Instance->runPythonCode((const char*)cmd.toAscii(), false, false); + Gui::Application::Instance->activeDocument()->commitCommand(); +} + +void ShapeBuilderWidget::createSolid() +{ + Gui::SelectionFilter partFilter ("SELECT Part::Feature COUNT 1"); + bool matchPart = partFilter.match(); + if (!matchPart) { + QMessageBox::critical(this, tr("Wrong selection"), tr("Select only one part object")); + return; + } + + QString line; + QTextStream str(&line); + + std::vector sel = partFilter.Result[0]; + std::vector::iterator it; + for (it=sel.begin();it!=sel.end();++it) { + str << "App.ActiveDocument." << it->getFeatName() << ".Shape"; + break; + } + + QString cmd; + cmd = QString::fromAscii( + "shell=%1\n" + "if shell.ShapeType != 'Shell': raise Exception('Part object is not a shell')\n" + "_=Part.Solid(shell)\n" + "if _.isNull(): raise Exception('Failed to create solid')\n" + "App.ActiveDocument.addObject('Part::Feature','Solid').Shape=_\n" + "del _\n" + ).arg(line); + + Gui::Application::Instance->activeDocument()->openCommand("Solid"); + Gui::Application::Instance->runPythonCode((const char*)cmd.toAscii(), false, false); + Gui::Application::Instance->activeDocument()->commitCommand(); +} + +void ShapeBuilderWidget::switchMode(int mode) +{ + Gui::Selection().clearSelection(); + if (mode == 0) { + d->gate->setMode(ShapeSelection::VERTEX); + d->ui.label->setText(tr("Select two vertices to create an edge")); + d->ui.checkPlanar->setEnabled(false); + d->ui.checkFaces->setEnabled(false); + } + else if (mode == 1) { + d->gate->setMode(ShapeSelection::EDGE); + d->ui.label->setText(tr("Select a closed set of edges")); + d->ui.checkPlanar->setEnabled(true); + d->ui.checkFaces->setEnabled(false); + } + else if (mode == 2) { + d->gate->setMode(ShapeSelection::FACE); + d->ui.label->setText(tr("Select adjacent faces")); + d->ui.checkPlanar->setEnabled(false); + d->ui.checkFaces->setEnabled(true); + } + else { + d->gate->setMode(ShapeSelection::ALL); + d->ui.label->setText(tr("You can select all shapes")); + d->ui.checkPlanar->setEnabled(false); + d->ui.checkFaces->setEnabled(false); + } +} + +bool ShapeBuilderWidget::accept() +{ + return true; +} + +bool ShapeBuilderWidget::reject() +{ + return true; +} + +void ShapeBuilderWidget::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + d->ui.retranslateUi(this); + } +} + + +/* TRANSLATOR PartGui::TaskShapeBuilder */ + +TaskShapeBuilder::TaskShapeBuilder() +{ + widget = new ShapeBuilderWidget(); + taskbox = new Gui::TaskView::TaskBox( + QPixmap(), widget->windowTitle(), true, 0); + taskbox->groupLayout()->addWidget(widget); + Content.push_back(taskbox); +} + +TaskShapeBuilder::~TaskShapeBuilder() +{ +} + +void TaskShapeBuilder::open() +{ +} + +void TaskShapeBuilder::clicked(int) +{ +} + +bool TaskShapeBuilder::accept() +{ + return widget->accept(); +} + +bool TaskShapeBuilder::reject() +{ + return widget->reject(); +} + +#include "moc_TaskShapeBuilder.cpp" diff --git a/src/Mod/Part/Gui/TaskShapeBuilder.h b/src/Mod/Part/Gui/TaskShapeBuilder.h new file mode 100644 index 0000000000..30217d5694 --- /dev/null +++ b/src/Mod/Part/Gui/TaskShapeBuilder.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (c) 2011 Werner Mayer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef PARTGUI_TASKSETCOLORS_H +#define PARTGUI_TASKSETCOLORS_H + +#include +#include + +namespace PartGui { + +class ShapeBuilderWidget : public QWidget +{ + Q_OBJECT + +public: + ShapeBuilderWidget(QWidget* parent = 0); + ~ShapeBuilderWidget(); + + bool accept(); + bool reject(); + +private Q_SLOTS: + void on_createButton_clicked(); + void switchMode(int); + +private: + void createEdge(); + void createFace(); + void createShell(); + void createSolid(); + void changeEvent(QEvent *e); + +private: + class Private; + Private* d; +}; + +class TaskShapeBuilder : public Gui::TaskView::TaskDialog +{ + Q_OBJECT + +public: + TaskShapeBuilder(); + ~TaskShapeBuilder(); + +public: + void open(); + bool accept(); + bool reject(); + void clicked(int); + + QDialogButtonBox::StandardButtons getStandardButtons() const + { return QDialogButtonBox::Close; } + +private: + ShapeBuilderWidget* widget; + Gui::TaskView::TaskBox* taskbox; +}; + +} //namespace PartGui + +#endif // PARTGUI_TASKSETCOLORS_H diff --git a/src/Mod/Part/Gui/TaskShapeBuilder.ui b/src/Mod/Part/Gui/TaskShapeBuilder.ui new file mode 100644 index 0000000000..2111f38db1 --- /dev/null +++ b/src/Mod/Part/Gui/TaskShapeBuilder.ui @@ -0,0 +1,116 @@ + + + PartGui::TaskShapeBuilder + + + + 0 + 0 + 220 + 259 + + + + Create shape + + + + + + Create shape + + + + + + Edge from vertices + + + + + + + Face from edges + + + + + + + Planar + + + + + + + Shell from faces + + + + + + + Solid from shell + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Create + + + + + + + + + All faces + + + + + + + + + + Qt::Vertical + + + + 20 + 127 + + + + + + + + TextLabel + + + + + + + + diff --git a/src/Mod/Part/Gui/Workbench.cpp b/src/Mod/Part/Gui/Workbench.cpp index d52a009776..14162ff6c9 100644 --- a/src/Mod/Part/Gui/Workbench.cpp +++ b/src/Mod/Part/Gui/Workbench.cpp @@ -66,7 +66,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const << "Part_MakeSolid" << "Part_ReverseShape" << "Part_SimpleCopy" << "Separator" << "Part_Boolean" << "Part_CrossSections" << "Part_Extrude" << "Part_Revolve" << "Part_Mirror" << "Part_Fillet" - << "Part_RuledSurface" << "Separator" << "Part_ShapeInfo"; + << "Part_RuledSurface" << "Part_Builder" << "Separator" << "Part_ShapeInfo"; Gui::MenuItem* partSimple = new Gui::MenuItem; root->insertItem(item, partSimple);