+ 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
This commit is contained in:
@@ -1251,7 +1251,7 @@ void Application::runCommand(bool bForce, const char* sCmd,...)
|
|||||||
free (format);
|
free (format);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::runPythonCode(const char* cmd, bool gui)
|
bool Application::runPythonCode(const char* cmd, bool gui, bool pyexc)
|
||||||
{
|
{
|
||||||
if (gui)
|
if (gui)
|
||||||
d->macroMngr->addLine(MacroManager::Gui,cmd);
|
d->macroMngr->addLine(MacroManager::Gui,cmd);
|
||||||
@@ -1263,8 +1263,13 @@ bool Application::runPythonCode(const char* cmd, bool gui)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Base::PyException &e) {
|
catch (Base::PyException &e) {
|
||||||
e.ReportException();
|
if (pyexc) {
|
||||||
Base::Console().Error("Stack Trace: %s\n",e.getStackTrace().c_str());
|
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&) {
|
catch (Base::AbortException&) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ public:
|
|||||||
Gui::CommandManager &commandManager(void);
|
Gui::CommandManager &commandManager(void);
|
||||||
/// Run a Python command
|
/// Run a Python command
|
||||||
void runCommand(bool bForce, const char* sCmd,...);
|
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
|
/// helper which create the commands
|
||||||
void createStandardOperations();
|
void createStandardOperations();
|
||||||
//@}
|
//@}
|
||||||
|
|||||||
@@ -433,14 +433,14 @@ SoFCUnifiedSelection::handleEvent(SoHandleEventAction * action)
|
|||||||
type = SoSelectionElementAction::Remove;
|
type = SoSelectionElementAction::Remove;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Gui::Selection().addSelection(documentName.c_str()
|
bool ok = Gui::Selection().addSelection(documentName.c_str()
|
||||||
,objectName.c_str()
|
,objectName.c_str()
|
||||||
,subElementName.c_str()
|
,subElementName.c_str()
|
||||||
,pp->getPoint()[0]
|
,pp->getPoint()[0]
|
||||||
,pp->getPoint()[1]
|
,pp->getPoint()[1]
|
||||||
,pp->getPoint()[2]);
|
,pp->getPoint()[2]);
|
||||||
|
if (ok)
|
||||||
type = SoSelectionElementAction::Append;
|
type = SoSelectionElementAction::Append;
|
||||||
if (mymode == OFF) {
|
if (mymode == OFF) {
|
||||||
snprintf(buf,512,"Selected: %s.%s.%s (%f,%f,%f)",documentName.c_str()
|
snprintf(buf,512,"Selected: %s.%s.%s (%f,%f,%f)",documentName.c_str()
|
||||||
,objectName.c_str()
|
,objectName.c_str()
|
||||||
@@ -458,23 +458,25 @@ SoFCUnifiedSelection::handleEvent(SoHandleEventAction * action)
|
|||||||
,objectName.c_str()
|
,objectName.c_str()
|
||||||
,subElementName.c_str())) {
|
,subElementName.c_str())) {
|
||||||
Gui::Selection().clearSelection(documentName.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()
|
,objectName.c_str()
|
||||||
,subElementName.c_str()
|
,subElementName.c_str()
|
||||||
,pp->getPoint()[0]
|
,pp->getPoint()[0]
|
||||||
,pp->getPoint()[1]
|
,pp->getPoint()[1]
|
||||||
,pp->getPoint()[2]);
|
,pp->getPoint()[2]);
|
||||||
type = SoSelectionElementAction::Append;
|
if (ok)
|
||||||
|
type = SoSelectionElementAction::Append;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Gui::Selection().clearSelection(documentName.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()
|
,objectName.c_str()
|
||||||
,0
|
,0
|
||||||
,pp->getPoint()[0]
|
,pp->getPoint()[0]
|
||||||
,pp->getPoint()[1]
|
,pp->getPoint()[1]
|
||||||
,pp->getPoint()[2]);
|
,pp->getPoint()[2]);
|
||||||
type = SoSelectionElementAction::All;
|
if (ok)
|
||||||
|
type = SoSelectionElementAction::All;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mymode == OFF) {
|
if (mymode == OFF) {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ set(PartGui_MOC_HDRS
|
|||||||
DlgSettings3DViewPartImp.h
|
DlgSettings3DViewPartImp.h
|
||||||
DlgSettingsGeneral.h
|
DlgSettingsGeneral.h
|
||||||
TaskFaceColors.h
|
TaskFaceColors.h
|
||||||
|
TaskShapeBuilder.h
|
||||||
)
|
)
|
||||||
fc_wrap_cpp(PartGui_MOC_SRCS ${PartGui_MOC_HDRS})
|
fc_wrap_cpp(PartGui_MOC_SRCS ${PartGui_MOC_HDRS})
|
||||||
SOURCE_GROUP("Moc" FILES ${PartGui_MOC_SRCS})
|
SOURCE_GROUP("Moc" FILES ${PartGui_MOC_SRCS})
|
||||||
@@ -60,6 +61,7 @@ set(PartGui_UIC_SRCS
|
|||||||
DlgSettings3DViewPart.ui
|
DlgSettings3DViewPart.ui
|
||||||
DlgSettingsGeneral.ui
|
DlgSettingsGeneral.ui
|
||||||
TaskFaceColors.ui
|
TaskFaceColors.ui
|
||||||
|
TaskShapeBuilder.ui
|
||||||
)
|
)
|
||||||
qt4_wrap_ui(PartGui_UIC_HDRS ${PartGui_UIC_SRCS})
|
qt4_wrap_ui(PartGui_UIC_HDRS ${PartGui_UIC_SRCS})
|
||||||
|
|
||||||
@@ -143,11 +145,14 @@ SET(PartGui_SRCS
|
|||||||
TaskFaceColors.cpp
|
TaskFaceColors.cpp
|
||||||
TaskFaceColors.h
|
TaskFaceColors.h
|
||||||
TaskFaceColors.ui
|
TaskFaceColors.ui
|
||||||
|
TaskShapeBuilder.cpp
|
||||||
|
TaskShapeBuilder.h
|
||||||
|
TaskShapeBuilder.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(PartGui_Scripts
|
SET(PartGui_Scripts
|
||||||
InitGui.py
|
InitGui.py
|
||||||
TestPartGui.py
|
TestPartGui.py
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
#include "CrossSections.h"
|
#include "CrossSections.h"
|
||||||
#include "Mirroring.h"
|
#include "Mirroring.h"
|
||||||
#include "ViewProvider.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);
|
DEF_STD_CMD_A(CmdShapeInfo);
|
||||||
|
|
||||||
CmdShapeInfo::CmdShapeInfo()
|
CmdShapeInfo::CmdShapeInfo()
|
||||||
@@ -1106,5 +1132,6 @@ void CreatePartCommands(void)
|
|||||||
rcCmdMgr.addCommand(new CmdPartPickCurveNet());
|
rcCmdMgr.addCommand(new CmdPartPickCurveNet());
|
||||||
rcCmdMgr.addCommand(new CmdShapeInfo());
|
rcCmdMgr.addCommand(new CmdShapeInfo());
|
||||||
rcCmdMgr.addCommand(new CmdPartRuledSurface());
|
rcCmdMgr.addCommand(new CmdPartRuledSurface());
|
||||||
|
rcCmdMgr.addCommand(new CmdPartBuilder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ BUILT_SOURCES=\
|
|||||||
ui_DlgSettingsGeneral.h \
|
ui_DlgSettingsGeneral.h \
|
||||||
ui_Mirroring.h \
|
ui_Mirroring.h \
|
||||||
ui_TaskFaceColors.h \
|
ui_TaskFaceColors.h \
|
||||||
|
ui_TaskShapeBuilder.h \
|
||||||
moc_CrossSections.cpp \
|
moc_CrossSections.cpp \
|
||||||
moc_DlgBooleanOperation.cpp \
|
moc_DlgBooleanOperation.cpp \
|
||||||
moc_DlgExtrusion.cpp \
|
moc_DlgExtrusion.cpp \
|
||||||
@@ -30,6 +31,7 @@ BUILT_SOURCES=\
|
|||||||
moc_DlgSettingsGeneral.cpp \
|
moc_DlgSettingsGeneral.cpp \
|
||||||
moc_Mirroring.cpp \
|
moc_Mirroring.cpp \
|
||||||
moc_TaskFaceColors.cpp \
|
moc_TaskFaceColors.cpp \
|
||||||
|
moc_TaskShapeBuilder.cpp \
|
||||||
qrc_Part.cpp
|
qrc_Part.cpp
|
||||||
|
|
||||||
libPartGui_la_SOURCES=\
|
libPartGui_la_SOURCES=\
|
||||||
@@ -64,6 +66,8 @@ libPartGui_la_SOURCES=\
|
|||||||
Mirroring.h \
|
Mirroring.h \
|
||||||
TaskFaceColors.cpp \
|
TaskFaceColors.cpp \
|
||||||
TaskFaceColors.h \
|
TaskFaceColors.h \
|
||||||
|
TaskShapeBuilder.cpp \
|
||||||
|
TaskShapeBuilder.h \
|
||||||
PreCompiled.cpp \
|
PreCompiled.cpp \
|
||||||
PreCompiled.h \
|
PreCompiled.h \
|
||||||
SoBrepShape.cpp \
|
SoBrepShape.cpp \
|
||||||
@@ -210,6 +214,7 @@ EXTRA_DIST = \
|
|||||||
DlgSettingsGeneral.ui \
|
DlgSettingsGeneral.ui \
|
||||||
Mirroring.ui \
|
Mirroring.ui \
|
||||||
TaskFaceColors.ui \
|
TaskFaceColors.ui \
|
||||||
|
TaskShapeBuilder.ui \
|
||||||
Resources/Part.qrc \
|
Resources/Part.qrc \
|
||||||
Resources/translations/Part_af.qm \
|
Resources/translations/Part_af.qm \
|
||||||
Resources/translations/Part_af.ts \
|
Resources/translations/Part_af.ts \
|
||||||
|
|||||||
407
src/Mod/Part/Gui/TaskShapeBuilder.cpp
Normal file
407
src/Mod/Part/Gui/TaskShapeBuilder.cpp
Normal file
@@ -0,0 +1,407 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2011 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||||
|
* *
|
||||||
|
* 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 <TopExp_Explorer.hxx>
|
||||||
|
# include <TopTools_IndexedMapOfShape.hxx>
|
||||||
|
# include <QButtonGroup>
|
||||||
|
# include <QMessageBox>
|
||||||
|
# include <QTextStream>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ui_TaskShapeBuilder.h"
|
||||||
|
#include "TaskShapeBuilder.h"
|
||||||
|
#include "ViewProviderExt.h"
|
||||||
|
|
||||||
|
#include <Gui/Application.h>
|
||||||
|
#include <Gui/Document.h>
|
||||||
|
#include <Gui/Selection.h>
|
||||||
|
#include <Gui/SelectionFilter.h>
|
||||||
|
|
||||||
|
#include <Base/Console.h>
|
||||||
|
#include <Base/Interpreter.h>
|
||||||
|
#include <App/Application.h>
|
||||||
|
#include <App/Document.h>
|
||||||
|
#include <App/DocumentObject.h>
|
||||||
|
#include <Mod/Part/App/PartFeature.h>
|
||||||
|
|
||||||
|
|
||||||
|
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<Gui::SelectionObject> sel = vertexFilter.Result[0];
|
||||||
|
std::vector<QString> elements;
|
||||||
|
std::vector<Gui::SelectionObject>::iterator it;
|
||||||
|
std::vector<std::string>::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<Gui::SelectionObject> sel = edgeFilter.Result[0];
|
||||||
|
std::vector<Gui::SelectionObject>::iterator it;
|
||||||
|
std::vector<std::string>::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<Gui::SelectionObject> sel = faceFilter.Result[0];
|
||||||
|
std::vector<Gui::SelectionObject>::iterator it;
|
||||||
|
std::vector<std::string>::const_iterator jt;
|
||||||
|
|
||||||
|
QString list;
|
||||||
|
QTextStream str(&list);
|
||||||
|
if (d->ui.checkFaces->isChecked()) {
|
||||||
|
std::set<App::DocumentObject*> obj;
|
||||||
|
for (it=sel.begin();it!=sel.end();++it)
|
||||||
|
obj.insert(it->getObject());
|
||||||
|
str << "[]";
|
||||||
|
for (std::set<App::DocumentObject*>::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<Gui::SelectionObject> sel = partFilter.Result[0];
|
||||||
|
std::vector<Gui::SelectionObject>::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"
|
||||||
83
src/Mod/Part/Gui/TaskShapeBuilder.h
Normal file
83
src/Mod/Part/Gui/TaskShapeBuilder.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2011 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||||
|
* *
|
||||||
|
* 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 <Gui/TaskView/TaskView.h>
|
||||||
|
#include <Gui/TaskView/TaskDialog.h>
|
||||||
|
|
||||||
|
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
|
||||||
116
src/Mod/Part/Gui/TaskShapeBuilder.ui
Normal file
116
src/Mod/Part/Gui/TaskShapeBuilder.ui
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>PartGui::TaskShapeBuilder</class>
|
||||||
|
<widget class="QWidget" name="PartGui::TaskShapeBuilder">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>220</width>
|
||||||
|
<height>259</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Create shape</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Create shape</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QRadioButton" name="radioButtonEdge">
|
||||||
|
<property name="text">
|
||||||
|
<string>Edge from vertices</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QRadioButton" name="radioButtonFace">
|
||||||
|
<property name="text">
|
||||||
|
<string>Face from edges</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QCheckBox" name="checkPlanar">
|
||||||
|
<property name="text">
|
||||||
|
<string>Planar</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QRadioButton" name="radioButtonShell">
|
||||||
|
<property name="text">
|
||||||
|
<string>Shell from faces</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QRadioButton" name="radioButtonSolid">
|
||||||
|
<property name="text">
|
||||||
|
<string>Solid from shell</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0" colspan="2">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="createButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Create</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QCheckBox" name="checkFaces">
|
||||||
|
<property name="text">
|
||||||
|
<string>All faces</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>127</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@@ -66,7 +66,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
|||||||
<< "Part_MakeSolid" << "Part_ReverseShape" << "Part_SimpleCopy" << "Separator"
|
<< "Part_MakeSolid" << "Part_ReverseShape" << "Part_SimpleCopy" << "Separator"
|
||||||
<< "Part_Boolean" << "Part_CrossSections" << "Part_Extrude"
|
<< "Part_Boolean" << "Part_CrossSections" << "Part_Extrude"
|
||||||
<< "Part_Revolve" << "Part_Mirror" << "Part_Fillet"
|
<< "Part_Revolve" << "Part_Mirror" << "Part_Fillet"
|
||||||
<< "Part_RuledSurface" << "Separator" << "Part_ShapeInfo";
|
<< "Part_RuledSurface" << "Part_Builder" << "Separator" << "Part_ShapeInfo";
|
||||||
|
|
||||||
Gui::MenuItem* partSimple = new Gui::MenuItem;
|
Gui::MenuItem* partSimple = new Gui::MenuItem;
|
||||||
root->insertItem(item, partSimple);
|
root->insertItem(item, partSimple);
|
||||||
|
|||||||
Reference in New Issue
Block a user