0000144: Add several tools to Part module

This commit is contained in:
wmayer 2012-06-09 13:50:33 +02:00
parent 0bf33b6466
commit 245cae03ef
10 changed files with 539 additions and 4 deletions

View File

@ -55,11 +55,11 @@ public:
/// are there any SubNames selected
bool hasSubNames(void)const { return SubNames.size() != 0; }
/// get the name of the Document of this SelctionObject
inline const char* getDocName(void) { return DocName.c_str(); }
inline const char* getDocName(void) const { return DocName.c_str(); }
/// get the name of the Document Object of this SelectionObject
inline const char* getFeatName(void) { return FeatName.c_str(); }
inline const char* getFeatName(void) const { return FeatName.c_str(); }
/// get the Type of the selcted Object
inline const char* getTypeName(void) { return TypeName.c_str(); }
inline const char* getTypeName(void) const { return TypeName.c_str(); }
/// returns the selected DocumentObject or NULL if the object is already deleted
const App::DocumentObject *getObject(void) const;

View File

@ -179,6 +179,7 @@ void PartExport initPart()
Part::Part2DObjectPython ::init();
Part::RuledSurface ::init();
Part::Loft ::init();
Part::Sweep ::init();
// Geometry types
Part::Geometry ::init();

View File

@ -196,3 +196,98 @@ App::DocumentObjectExecReturn *Loft::execute(void)
return new App::DocumentObjectExecReturn(e->GetMessageString());
}
}
// ----------------------------------------------------------------------------
PROPERTY_SOURCE(Part::Sweep, Part::Feature)
Sweep::Sweep()
{
ADD_PROPERTY_TYPE(Sections,(0),"Sweep",App::Prop_None,"List of sections");
Sections.setSize(0);
ADD_PROPERTY_TYPE(Spine,(0),"Sweep",App::Prop_None,"Path to sweep along");
ADD_PROPERTY_TYPE(Solid,(false),"Sweep",App::Prop_None,"Create solid");
ADD_PROPERTY_TYPE(Fresnet,(false),"Sweep",App::Prop_None,"Fresnet");
}
short Sweep::mustExecute() const
{
if (Sections.isTouched())
return 1;
if (Spine.isTouched())
return 1;
if (Solid.isTouched())
return 1;
if (Fresnet.isTouched())
return 1;
return 0;
}
void Sweep::onChanged(const App::Property* prop)
{
Part::Feature::onChanged(prop);
}
App::DocumentObjectExecReturn *Sweep::execute(void)
{
if (Sections.getSize() == 0)
return new App::DocumentObjectExecReturn("No sections linked.");
App::DocumentObject* spine = Spine.getValue();
if (!(spine && spine->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())))
return new App::DocumentObjectExecReturn("No shape linked.");
const std::vector<std::string>& subedge = Spine.getSubValues();
if (subedge.size() != 1)
return new App::DocumentObjectExecReturn("Not exactly one sub-shape linked.");
TopoDS_Shape edge;
const Part::TopoShape& shape = static_cast<Part::Feature*>(spine)->Shape.getValue();
if (!shape._Shape.IsNull()) {
if (!subedge[0].empty()) {
edge = shape.getSubShape(subedge[0].c_str());
}
else {
if (shape._Shape.ShapeType() == TopAbs_EDGE)
edge = shape._Shape;
else if (shape._Shape.ShapeType() == TopAbs_WIRE)
edge = shape._Shape;
}
}
try {
TopTools_ListOfShape profiles;
const std::vector<App::DocumentObject*>& shapes = Sections.getValues();
std::vector<App::DocumentObject*>::const_iterator it;
for (it = shapes.begin(); it != shapes.end(); ++it) {
if (!(*it)->isDerivedFrom(Part::Feature::getClassTypeId()))
return new App::DocumentObjectExecReturn("Linked object is not a shape.");
const TopoDS_Shape& shape = static_cast<Part::Feature*>(*it)->Shape.getValue();
if (shape.IsNull())
return new App::DocumentObjectExecReturn("Linked shape is invalid.");
if (shape.ShapeType() == TopAbs_WIRE) {
profiles.Append(shape);
}
else if (shape.ShapeType() == TopAbs_EDGE) {
BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(shape));
profiles.Append(mkWire.Wire());
}
else if (shape.ShapeType() == TopAbs_VERTEX) {
profiles.Append(shape);
}
else {
return new App::DocumentObjectExecReturn("Linked shape is not a vertex, edge nor wire.");
}
}
Standard_Boolean isSolid = Solid.getValue() ? Standard_True : Standard_False;
Standard_Boolean isFresnet = Fresnet.getValue() ? Standard_True : Standard_False;
BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(edge));
TopoShape myShape(mkWire.Wire());
this->Shape.setValue(myShape.makePipeShell(profiles, isSolid, isFresnet));
return App::DocumentObject::StdReturn;
}
catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();
return new App::DocumentObjectExecReturn(e->GetMessageString());
}
}

View File

@ -73,6 +73,29 @@ protected:
void onChanged (const App::Property* prop);
};
class Sweep : public Part::Feature
{
PROPERTY_HEADER(Part::Sweep);
public:
Sweep();
App::PropertyLinkList Sections;
App::PropertyLinkSub Spine;
App::PropertyBool Solid;
App::PropertyBool Fresnet;
/** @name methods override feature */
//@{
/// recalculate the feature
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
//@}
protected:
void onChanged (const App::Property* prop);
};
} //namespace Part

View File

@ -41,6 +41,7 @@ set(PartGui_MOC_HDRS
TaskFaceColors.h
TaskShapeBuilder.h
TaskLoft.h
TaskSweep.h
)
fc_wrap_cpp(PartGui_MOC_SRCS ${PartGui_MOC_HDRS})
SOURCE_GROUP("Moc" FILES ${PartGui_MOC_SRCS})
@ -65,6 +66,7 @@ set(PartGui_UIC_SRCS
TaskFaceColors.ui
TaskShapeBuilder.ui
TaskLoft.ui
TaskSweep.ui
)
qt4_wrap_ui(PartGui_UIC_HDRS ${PartGui_UIC_SRCS})
@ -155,6 +157,9 @@ SET(PartGui_SRCS
TaskLoft.cpp
TaskLoft.h
TaskLoft.ui
TaskSweep.cpp
TaskSweep.h
TaskSweep.ui
)
SET(PartGui_Scripts

View File

@ -61,6 +61,7 @@
#include "ViewProvider.h"
#include "TaskShapeBuilder.h"
#include "TaskLoft.h"
#include "TaskSweep.h"
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@ -960,6 +961,31 @@ bool CmdPartLoft::isActive(void)
//--------------------------------------------------------------------------------------
DEF_STD_CMD_A(CmdPartSweep);
CmdPartSweep::CmdPartSweep()
: Command("Part_Sweep")
{
sAppModule = "Part";
sGroup = QT_TR_NOOP("Part");
sMenuText = QT_TR_NOOP("Sweep...");
sToolTipText = QT_TR_NOOP("Advanced utility to sweep");
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
}
void CmdPartSweep::activated(int iMsg)
{
Gui::Control().showDialog(new PartGui::TaskSweep());
}
bool CmdPartSweep::isActive(void)
{
return (hasActiveDocument() && !Gui::Control().activeDialog());
}
//--------------------------------------------------------------------------------------
DEF_STD_CMD_A(CmdShapeInfo);
CmdShapeInfo::CmdShapeInfo()
@ -1194,5 +1220,6 @@ void CreatePartCommands(void)
rcCmdMgr.addCommand(new CmdPartRuledSurface());
rcCmdMgr.addCommand(new CmdPartBuilder());
rcCmdMgr.addCommand(new CmdPartLoft());
rcCmdMgr.addCommand(new CmdPartSweep());
}

View File

@ -0,0 +1,243 @@
/***************************************************************************
* 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 <QMessageBox>
# include <QTextStream>
#endif
#include "ui_TaskSweep.h"
#include "TaskSweep.h"
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/Selection.h>
#include <Gui/SelectionFilter.h>
#include <Gui/ViewProvider.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;
class SweepWidget::Private
{
public:
Ui_TaskSweep ui;
std::string document;
Private()
{
}
~Private()
{
}
};
/* TRANSLATOR PartGui::SweepWidget */
SweepWidget::SweepWidget(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.selector->setAvailableLabel(tr("Vertex/Wire"));
d->ui.selector->setSelectedLabel(tr("Sweep"));
connect(d->ui.selector->availableTreeWidget(), SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
this, SLOT(onCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
connect(d->ui.selector->selectedTreeWidget(), SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
this, SLOT(onCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
findShapes();
}
SweepWidget::~SweepWidget()
{
delete d;
}
void SweepWidget::findShapes()
{
App::Document* activeDoc = App::GetApplication().getActiveDocument();
Gui::Document* activeGui = Gui::Application::Instance->getDocument(activeDoc);
if (!activeGui) return;
d->document = activeDoc->getName();
std::vector<Part::Feature*> objs = activeDoc->getObjectsOfType<Part::Feature>();
for (std::vector<Part::Feature*>::iterator it = objs.begin(); it!=objs.end(); ++it) {
const TopoDS_Shape& shape = (*it)->Shape.getValue();
if (shape.IsNull()) continue;
if (shape.ShapeType() == TopAbs_WIRE ||
shape.ShapeType() == TopAbs_EDGE ||
shape.ShapeType() == TopAbs_VERTEX) {
QString label = QString::fromUtf8((*it)->Label.getValue());
QString name = QString::fromAscii((*it)->getNameInDocument());
QTreeWidgetItem* child = new QTreeWidgetItem();
child->setText(0, label);
child->setToolTip(0, label);
child->setData(0, Qt::UserRole, name);
Gui::ViewProvider* vp = activeGui->getViewProvider(*it);
if (vp) child->setIcon(0, vp->getIcon());
d->ui.selector->availableTreeWidget()->addTopLevelItem(child);
}
}
}
bool SweepWidget::accept()
{
Gui::SelectionFilter edgeFilter ("SELECT Part::Feature SUBELEMENT Edge COUNT 1");
if (!edgeFilter.match()) {
QMessageBox::critical(this, tr("Sweep path"), tr("Select an edge you want to sweep along."));
return false;
}
// get the selected object
const std::vector<Gui::SelectionObject>& result = edgeFilter.Result[0];
const std::vector<std::string>& edges = result[0].getSubNames();
QString list, solid, fresnet;
if (d->ui.checkSolid->isChecked())
solid = QString::fromAscii("True");
else
solid = QString::fromAscii("False");
if (d->ui.checkFresnet->isChecked())
fresnet = QString::fromAscii("True");
else
fresnet = QString::fromAscii("False");
QTextStream str(&list);
int count = d->ui.selector->selectedTreeWidget()->topLevelItemCount();
if (count < 1) {
QMessageBox::critical(this, tr("Too few elements"), tr("At least one edge or wire is required."));
return false;
}
for (int i=0; i<count; i++) {
QTreeWidgetItem* child = d->ui.selector->selectedTreeWidget()->topLevelItem(i);
QString name = child->data(0, Qt::UserRole).toString();
str << "App.getDocument('" << d->document.c_str() << "')." << name << ", ";
}
try {
QString cmd;
cmd = QString::fromAscii(
"App.getDocument('%6').addObject('Part::Sweep','Sweep')\n"
"App.getDocument('%6').ActiveObject.Sections=[%1]\n"
"App.getDocument('%6').ActiveObject.Spine=(FreeCAD.ActiveDocument.%2,['%3'])\n"
"App.getDocument('%6').ActiveObject.Solid=%4\n"
"App.getDocument('%6').ActiveObject.Fresnet=%5\n"
)
.arg(list).arg(QLatin1String(result.front().getFeatName()))
.arg(QLatin1String(edges.front().c_str()))
.arg(solid).arg(fresnet).arg(QString::fromAscii(d->document.c_str()));
Gui::Document* doc = Gui::Application::Instance->getDocument(d->document.c_str());
if (!doc) throw Base::Exception("Document doesn't exist anymore");
doc->openCommand("Sweep");
Gui::Application::Instance->runPythonCode((const char*)cmd.toAscii(), false, false);
doc->commitCommand();
doc->getDocument()->recompute();
}
catch (const Base::Exception& e) {
Base::Console().Error("%s\n", e.what());
return false;
}
return true;
}
bool SweepWidget::reject()
{
return true;
}
void SweepWidget::onCurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous)
{
if (previous) {
Gui::Selection().rmvSelection(d->document.c_str(),
(const char*)previous->data(0,Qt::UserRole).toByteArray());
}
if (current) {
Gui::Selection().addSelection(d->document.c_str(),
(const char*)current->data(0,Qt::UserRole).toByteArray());
}
}
void SweepWidget::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
d->ui.retranslateUi(this);
d->ui.selector->setAvailableLabel(tr("Vertex/Wire"));
d->ui.selector->setSelectedLabel(tr("Sweep"));
}
}
/* TRANSLATOR PartGui::TaskSweep */
TaskSweep::TaskSweep()
{
widget = new SweepWidget();
taskbox = new Gui::TaskView::TaskBox(
QPixmap(), widget->windowTitle(), true, 0);
taskbox->groupLayout()->addWidget(widget);
Content.push_back(taskbox);
}
TaskSweep::~TaskSweep()
{
}
void TaskSweep::open()
{
}
void TaskSweep::clicked(int)
{
}
bool TaskSweep::accept()
{
return widget->accept();
}
bool TaskSweep::reject()
{
return widget->reject();
}
#include "moc_TaskSweep.cpp"

View File

@ -0,0 +1,81 @@
/***************************************************************************
* 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_TASKSWEEP_H
#define PARTGUI_TASKSWEEP_H
#include <Gui/TaskView/TaskView.h>
#include <Gui/TaskView/TaskDialog.h>
class QTreeWidgetItem;
namespace PartGui {
class SweepWidget : public QWidget
{
Q_OBJECT
public:
SweepWidget(QWidget* parent = 0);
~SweepWidget();
bool accept();
bool reject();
private Q_SLOTS:
void onCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*);
private:
void changeEvent(QEvent *e);
void findShapes();
private:
class Private;
Private* d;
};
class TaskSweep : public Gui::TaskView::TaskDialog
{
Q_OBJECT
public:
TaskSweep();
~TaskSweep();
public:
void open();
bool accept();
bool reject();
void clicked(int);
QDialogButtonBox::StandardButtons getStandardButtons() const
{ return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; }
private:
SweepWidget* widget;
Gui::TaskView::TaskBox* taskbox;
};
} //namespace PartGui
#endif // PARTGUI_TASKSWEEP_H

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PartGui::TaskSweep</class>
<widget class="QWidget" name="PartGui::TaskSweep">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>336</width>
<height>326</height>
</rect>
</property>
<property name="windowTitle">
<string>Sweep</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="3">
<widget class="Gui::ActionSelector" name="selector"/>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkSolid">
<property name="text">
<string>Create solid</string>
</property>
</widget>
</item>
<item row="1" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>130</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkFresnet">
<property name="text">
<string>Fresnet</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Gui::ActionSelector</class>
<extends>QWidget</extends>
<header>Gui/Widgets.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../../../Gui/Icons/resource.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -72,7 +72,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
<< "Part_RefineShape" << "Separator"
<< "Part_Boolean" << "Part_CrossSections" << "Part_Extrude"
<< "Part_Revolve" << "Part_Mirror" << "Part_Fillet" << "Part_Chamfer"
<< "Part_RuledSurface" << "Part_Loft"
<< "Part_RuledSurface" << "Part_Loft" << "Part_Sweep"
<< "Part_Builder";
//Gui::MenuItem* partSimple = new Gui::MenuItem;