Files
create/src/Mod/Part/Gui/DlgExtrusion.cpp
2024-08-26 17:56:58 +02:00

786 lines
27 KiB
C++

/***************************************************************************
* Copyright (c) 2008 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 <BRepAdaptor_Curve.hxx>
# include <BRep_Tool.hxx>
# include <Precision.hxx>
# include <ShapeExtend_Explorer.hxx>
# include <TopExp_Explorer.hxx>
# include <TopoDS.hxx>
# include <TopTools_HSequenceOfShape.hxx>
# include <QKeyEvent>
# include <QMessageBox>
#endif
#include <App/Application.h>
#include <App/Document.h>
#include <App/DocumentObject.h>
#include <App/Link.h>
#include <App/Part.h>
#include <Base/UnitsApi.h>
#include <Gui/Application.h>
#include <Gui/BitmapFactory.h>
#include <Gui/Command.h>
#include <Gui/Document.h>
#include <Gui/Utilities.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include "ui_DlgExtrusion.h"
#include "DlgExtrusion.h"
FC_LOG_LEVEL_INIT("Part",true,true)
using namespace PartGui;
class DlgExtrusion::EdgeSelection : public Gui::SelectionFilterGate
{
public:
bool canSelect;
EdgeSelection()
: Gui::SelectionFilterGate(nullPointer())
{
canSelect = false;
}
bool allow(App::Document* /*pDoc*/, App::DocumentObject* pObj, const char* sSubName) override
{
this->canSelect = false;
if (!sSubName || sSubName[0] == '\0')
return false;
std::string element(sSubName);
if (element.substr(0,4) != "Edge")
return false;
Part::TopoShape part = Part::Feature::getTopoShape(pObj);
if (part.isNull()) {
return false;
}
try {
TopoDS_Shape sub = Part::Feature::getTopoShape(pObj, sSubName, true /*need element*/).getShape();
if (!sub.IsNull() && sub.ShapeType() == TopAbs_EDGE) {
const TopoDS_Edge& edge = TopoDS::Edge(sub);
BRepAdaptor_Curve adapt(edge);
if (adapt.GetType() == GeomAbs_Line) {
this->canSelect = true;
return true;
}
}
}
catch (...) {
}
return false;
}
};
DlgExtrusion::DlgExtrusion(QWidget* parent, Qt::WindowFlags fl)
: QDialog(parent, fl), ui(new Ui_DlgExtrusion), filter(nullptr)
{
ui->setupUi(this);
setupConnections();
ui->statusLabel->clear();
ui->dirX->setDecimals(Base::UnitsApi::getDecimals());
ui->dirY->setDecimals(Base::UnitsApi::getDecimals());
ui->dirZ->setDecimals(Base::UnitsApi::getDecimals());
ui->spinLenFwd->setUnit(Base::Unit::Length);
ui->spinLenFwd->setValue(10.0);
ui->spinLenRev->setUnit(Base::Unit::Length);
ui->spinTaperAngle->setUnit(Base::Unit::Angle);
ui->spinTaperAngle->setUnit(Base::Unit::Angle);
findShapes();
Gui::ItemViewSelection sel(ui->treeWidget);
sel.applyFrom(Gui::Selection().getObjectsOfType(Part::Feature::getClassTypeId()));
sel.applyFrom(Gui::Selection().getObjectsOfType(App::Link::getClassTypeId()));
sel.applyFrom(Gui::Selection().getObjectsOfType(App::Part::getClassTypeId()));
this->onDirModeChanged();
ui->spinLenFwd->selectAll();
// Make sure that the spin box has the focus to get key events
// Calling setFocus() directly doesn't work because the spin box is not
// yet visible.
QMetaObject::invokeMethod(ui->spinLenFwd, "setFocus", Qt::QueuedConnection);
this->autoSolid();
}
/*
* Destroys the object and frees any allocated resources
*/
DlgExtrusion::~DlgExtrusion()
{
if (filter){
Gui::Selection().rmvSelectionGate();
filter = nullptr;
}
// no need to delete child widgets, Qt does it all for us
}
void DlgExtrusion::setupConnections()
{
// clang-format off
connect(ui->rbDirModeCustom, &QRadioButton::toggled,
this, &DlgExtrusion::onDirModeCustomToggled);
connect(ui->rbDirModeEdge, &QRadioButton::toggled,
this, &DlgExtrusion::onDirModeEdgeToggled);
connect(ui->rbDirModeNormal, &QRadioButton::toggled,
this, &DlgExtrusion::onDirModeNormalToggled);
connect(ui->btnSelectEdge, &QPushButton::clicked,
this, &DlgExtrusion::onSelectEdgeClicked);
connect(ui->btnX, &QPushButton::clicked,
this, &DlgExtrusion::onButtnoXClicked);
connect(ui->btnY, &QPushButton::clicked,
this, &DlgExtrusion::onButtonYClicked);
connect(ui->btnZ, &QPushButton::clicked,
this, &DlgExtrusion::onButtonZClicked);
connect(ui->chkSymmetric, &QCheckBox::toggled,
this, &DlgExtrusion::onCheckSymmetricToggled);
connect(ui->txtLink, &QLineEdit::textChanged,
this, &DlgExtrusion::onTextLinkTextChanged);
// clang-format on
}
void DlgExtrusion::changeEvent(QEvent *e)
{
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
}
QDialog::changeEvent(e);
}
void DlgExtrusion::keyPressEvent(QKeyEvent* ke)
{
// The extrusion dialog is embedded into a task panel
// which is a parent widget and will handle the event
ke->ignore();
}
void DlgExtrusion::onDirModeCustomToggled(bool on)
{
if(on) //this check prevents dual fire of dirmode changed - on radio buttons, one will come on, and other will come off, causing two events.
this->onDirModeChanged();
}
void DlgExtrusion::onDirModeEdgeToggled(bool on)
{
if(on)
this->onDirModeChanged();
}
void DlgExtrusion::onDirModeNormalToggled(bool on)
{
if(on)
this->onDirModeChanged();
}
void DlgExtrusion::onSelectEdgeClicked()
{
if (!filter) {
filter = new EdgeSelection();
Gui::Selection().addSelectionGate(filter);
ui->btnSelectEdge->setText(tr("Selecting..."));
//visibility automation
try{
QString code = QString::fromLatin1(
"import Show\n"
"tv = Show.TempoVis(App.ActiveDocument, tag= 'PartGui::DlgExtrusion')\n"
"tv.hide([%1])"
);
std::vector<App::DocumentObject*>sources = getShapesToExtrude();
QString features_to_hide;
for (App::DocumentObject* obj: sources){
if (!obj)
continue;
features_to_hide.append(QString::fromLatin1("App.ActiveDocument."));
features_to_hide.append(QString::fromLatin1(obj->getNameInDocument()));
features_to_hide.append(QString::fromLatin1(", \n"));
}
QByteArray code_2 = code.arg(features_to_hide).toLatin1();
Base::Interpreter().runString(code_2.constData());
} catch (Base::PyException &e){
e.ReportException();
}
} else {
Gui::Selection().rmvSelectionGate();
filter = nullptr;
ui->btnSelectEdge->setText(tr("Select"));
//visibility automation
try{
Base::Interpreter().runString("del(tv)");
} catch (Base::PyException &e){
e.ReportException();
}
}
}
void DlgExtrusion::onButtnoXClicked()
{
Base::Vector3d axis(1.0, 0.0, 0.0);
if ((getDir() - axis).Length() < 1e-7)
axis = axis * (-1);
setDirMode(Part::Extrusion::dmCustom);
setDir(axis);
}
void DlgExtrusion::onButtonYClicked()
{
Base::Vector3d axis(0.0, 1.0, 0.0);
if ((getDir() - axis).Length() < 1e-7)
axis = axis * (-1);
setDirMode(Part::Extrusion::dmCustom);
setDir(axis);
}
void DlgExtrusion::onButtonZClicked()
{
Base::Vector3d axis(0.0, 0.0, 1.0);
if ((getDir() - axis).Length() < 1e-7)
axis = axis * (-1);
setDirMode(Part::Extrusion::dmCustom);
setDir(axis);
}
void DlgExtrusion::onCheckSymmetricToggled(bool on)
{
ui->spinLenRev->setEnabled(!on);
}
void DlgExtrusion::onTextLinkTextChanged(QString)
{
this->fetchDir();
}
void DlgExtrusion::onDirModeChanged()
{
Part::Extrusion::eDirMode dirMode = this->getDirMode();
ui->dirX->setEnabled(dirMode == Part::Extrusion::dmCustom);
ui->dirY->setEnabled(dirMode == Part::Extrusion::dmCustom);
ui->dirZ->setEnabled(dirMode == Part::Extrusion::dmCustom);
ui->txtLink->setEnabled(dirMode == Part::Extrusion::dmEdge);
this->fetchDir();
}
void DlgExtrusion::onSelectionChanged(const Gui::SelectionChanges& msg)
{
if (msg.Type == Gui::SelectionChanges::AddSelection) {
if (filter && filter->canSelect) {
this->setAxisLink(msg.pObjectName, msg.pSubName);
this->setDirMode(Part::Extrusion::dmEdge);
}
}
}
App::DocumentObject& DlgExtrusion::getShapeToExtrude() const
{
std::vector<App::DocumentObject*> objs = this->getShapesToExtrude();
if (objs.empty())
throw Base::ValueError("No shapes selected");
return *(objs[0]);
}
void DlgExtrusion::fetchDir()
{
bool lengths_are_at_defaults =
(fabs(ui->spinLenFwd->value().getValue() - 10.0) < 1e-7)
&& (fabs(ui->spinLenRev->value().getValue() - 0.0) < 1e-7);
bool lengths_are_zero =
(fabs(ui->spinLenFwd->value().getValue() - 0.0) < 1e-7)
&& (fabs(ui->spinLenRev->value().getValue() - 0.0) < 1e-7);
try{
Base::Vector3d pos, dir;
bool fetched = false;
bool dir_has_valid_magnitude = false;
if(this->getDirMode() == Part::Extrusion::dmEdge){
App::PropertyLinkSub lnk; this->getAxisLink(lnk);
fetched = Part::Extrusion::fetchAxisLink(lnk, pos, dir);
dir_has_valid_magnitude = fetched;
} else if (this->getDirMode() == Part::Extrusion::dmNormal){
App::PropertyLink lnk;
lnk.setValue(&this->getShapeToExtrude());
dir = Part::Extrusion::calculateShapeNormal(lnk);
fetched = true;
}
if (dir_has_valid_magnitude && lengths_are_at_defaults){
ui->spinLenFwd->setValue(0);
} else if (!dir_has_valid_magnitude && lengths_are_zero){
ui->spinLenFwd->setValue(1.0);
}
if (fetched){
this->setDir(dir);
}
} catch (Base::Exception &){
} catch (...){
}
}
void DlgExtrusion::autoSolid()
{
try{
App::DocumentObject* dobj = &this->getShapeToExtrude();
Part::TopoShape shape = Part::Feature::getTopoShape(dobj);
if (shape.isNull()) {
return;
}
TopoDS_Shape sh = shape.getShape();
if (sh.IsNull())
return;
ShapeExtend_Explorer xp;
Handle(TopTools_HSequenceOfShape) leaves = xp.SeqFromCompound(sh, /*recursive= */Standard_True);
int cntClosedWires = 0;
for(int i = 0; i < leaves->Length(); i++){
const TopoDS_Shape &leaf = leaves->Value(i+1);
if (leaf.IsNull())
return;
if (leaf.ShapeType() == TopAbs_WIRE || leaf.ShapeType() == TopAbs_EDGE){
if (BRep_Tool::IsClosed(leaf)){
cntClosedWires++;
}
}
}
ui->chkSolid->setChecked( cntClosedWires == leaves->Length() );
} catch(...) {
}
}
void DlgExtrusion::findShapes()
{
App::Document* activeDoc = App::GetApplication().getActiveDocument();
if (!activeDoc)
return;
Gui::Document* activeGui = Gui::Application::Instance->getDocument(activeDoc);
this->document = activeDoc->getName();
this->label = activeDoc->Label.getValue();
std::vector<App::DocumentObject*> objs = activeDoc->getObjectsOfType<App::DocumentObject>();
for (auto obj : objs) {
Part::TopoShape topoShape = Part::Feature::getTopoShape(obj);
if (topoShape.isNull()) {
continue;
}
TopoDS_Shape shape = topoShape.getShape();
if (shape.IsNull()) continue;
if (canExtrude(shape)) {
QTreeWidgetItem* item = new QTreeWidgetItem(ui->treeWidget);
item->setText(0, QString::fromUtf8(obj->Label.getValue()));
item->setData(0, Qt::UserRole, QString::fromLatin1(obj->getNameInDocument()));
Gui::ViewProvider* vp = activeGui->getViewProvider(obj);
if (vp)
item->setIcon(0, vp->getIcon());
}
}
}
bool DlgExtrusion::canExtrude(const TopoDS_Shape& shape) const
{
if (shape.IsNull())
return false;
TopAbs_ShapeEnum type = shape.ShapeType();
if (type == TopAbs_VERTEX || type == TopAbs_EDGE ||
type == TopAbs_WIRE || type == TopAbs_FACE ||
type == TopAbs_SHELL)
return true;
if (type == TopAbs_COMPOUND) {
TopExp_Explorer xp;
xp.Init(shape,TopAbs_SOLID);
while (xp.More()) {
return false;
}
xp.Init(shape,TopAbs_COMPSOLID);
while (xp.More()) {
return false;
}
return true;
}
return false;
}
void DlgExtrusion::accept()
{
try{
apply();
QDialog::accept();
} catch (Base::AbortException&){
};
}
void DlgExtrusion::apply()
{
try{
if (!validate())
throw Base::AbortException();
if (filter) //if still selecting edge - stop. This is important for visibility automation.
this->onSelectEdgeClicked();
Gui::WaitCursor wc;
App::Document* activeDoc = App::GetApplication().getDocument(this->document.c_str());
if (!activeDoc) {
QMessageBox::critical(this, windowTitle(),
tr("The document '%1' doesn't exist.").arg(QString::fromUtf8(this->label.c_str())));
return;
}
activeDoc->openTransaction("Extrude");
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part");
bool addBaseName = hGrp->GetBool("AddBaseObjectName", false);
std::vector<App::DocumentObject*> objects = this->getShapesToExtrude();
for (App::DocumentObject* sourceObj: objects) {
assert(sourceObj);
if (Part::Feature::getTopoShape(sourceObj).isNull()){
FC_ERR("Object " << sourceObj->getFullName()
<< " is not Part object (has no OCC shape). Can't extrude it.");
continue;
}
std::string name;
name = sourceObj->getDocument()->getUniqueObjectName("Extrude").c_str();
if (addBaseName) {
//FIXME: implement
//QString baseName = QString::fromLatin1("Extrude_%1").arg(sourceObjectName);
//label = QString::fromLatin1("%1_Extrude").arg((*it)->text(0));
}
FCMD_OBJ_DOC_CMD(sourceObj,"addObject('Part::Extrusion','" << name << "')");
auto newObj = sourceObj->getDocument()->getObject(name.c_str());
this->writeParametersToFeature(*newObj, sourceObj);
Gui::Command::copyVisual(newObj, "ShapeAppearance", sourceObj);
Gui::Command::copyVisual(newObj, "LineColor", sourceObj);
Gui::Command::copyVisual(newObj, "PointColor", sourceObj);
FCMD_OBJ_HIDE(sourceObj);
}
activeDoc->commitTransaction();
Gui::Command::updateActive();
}
catch (Base::AbortException&){
throw;
}
catch (Base::Exception &err){
QMessageBox::critical(this,
windowTitle(),
tr("Creating Extrusion failed.\n%1")
.arg(QCoreApplication::translate("Exception", err.what())));
return;
}
catch(...) {
QMessageBox::critical(this, windowTitle(),
tr("Creating Extrusion failed.\n%1").arg(QString::fromUtf8("Unknown error")));
return;
}
}
void DlgExtrusion::reject()
{
if (filter) //if still selecting edge - stop.
this->onSelectEdgeClicked();
QDialog::reject();
}
Base::Vector3d DlgExtrusion::getDir() const
{
return Base::Vector3d(
ui->dirX->value(),
ui->dirY->value(),
ui->dirZ->value());
}
void DlgExtrusion::setDir(Base::Vector3d newDir)
{
ui->dirX->setValue(newDir.x);
ui->dirY->setValue(newDir.y);
ui->dirZ->setValue(newDir.z);
}
Part::Extrusion::eDirMode DlgExtrusion::getDirMode() const
{
if(ui->rbDirModeCustom->isChecked())
return Part::Extrusion::dmCustom;
if(ui->rbDirModeEdge->isChecked())
return Part::Extrusion::dmEdge;
if(ui->rbDirModeNormal->isChecked())
return Part::Extrusion::dmNormal;
//we shouldn't get here...
return Part::Extrusion::dmCustom;
}
void DlgExtrusion::setDirMode(Part::Extrusion::eDirMode newMode)
{
ui->rbDirModeCustom->blockSignals(true);
ui->rbDirModeEdge->blockSignals(true);
ui->rbDirModeNormal->blockSignals(true);
ui->rbDirModeCustom->setChecked(newMode == Part::Extrusion::dmCustom);
ui->rbDirModeEdge->setChecked(newMode == Part::Extrusion::dmEdge);
ui->rbDirModeNormal->setChecked(newMode == Part::Extrusion::dmNormal);
ui->rbDirModeCustom->blockSignals(false);
ui->rbDirModeEdge->blockSignals(false);
ui->rbDirModeNormal->blockSignals(false);
this->onDirModeChanged();
}
void DlgExtrusion::getAxisLink(App::PropertyLinkSub& lnk) const
{
QString text = ui->txtLink->text();
if (text.length() == 0) {
lnk.setValue(nullptr);
} else {
QStringList parts = text.split(QChar::fromLatin1(':'));
App::DocumentObject* obj = App::GetApplication().getActiveDocument()->getObject(parts[0].toLatin1());
if(!obj){
throw Base::ValueError(tr("Object not found: %1").arg(parts[0]).toUtf8().constData());
}
lnk.setValue(obj);
if (parts.size() == 1) {
return;
} else if (parts.size() == 2) {
std::vector<std::string> subs;
subs.emplace_back(parts[1].toLatin1().constData());
lnk.setValue(obj,subs);
}
}
}
void DlgExtrusion::setAxisLink(const App::PropertyLinkSub& lnk)
{
if (!lnk.getValue()){
ui->txtLink->clear();
return;
}
if (lnk.getSubValues().size() == 1){
this->setAxisLink(lnk.getValue()->getNameInDocument(), lnk.getSubValues()[0].c_str());
} else {
this->setAxisLink(lnk.getValue()->getNameInDocument(), "");
}
}
void DlgExtrusion::setAxisLink(const char* objname, const char* subname)
{
if(objname && strlen(objname) > 0){
QString txt = QString::fromLatin1(objname);
if (subname && strlen(subname) > 0){
txt = txt + QString::fromLatin1(":") + QString::fromLatin1(subname);
}
ui->txtLink->setText(txt);
} else {
ui->txtLink->clear();
}
}
std::vector<App::DocumentObject*> DlgExtrusion::getShapesToExtrude() const
{
QList<QTreeWidgetItem *> items = ui->treeWidget->selectedItems();
App::Document* doc = App::GetApplication().getDocument(this->document.c_str());
if (!doc)
throw Base::RuntimeError("Document lost");
std::vector<App::DocumentObject*> objects;
for (auto item : items) {
App::DocumentObject* obj = doc->getObject(item->data(0, Qt::UserRole).toString().toLatin1());
if (!obj)
throw Base::RuntimeError("Object not found");
objects.push_back(obj);
}
return objects;
}
bool DlgExtrusion::validate()
{
//check source shapes
if (ui->treeWidget->selectedItems().isEmpty()) {
QMessageBox::critical(this, windowTitle(),
tr("No shapes selected for extrusion. Select some, first."));
return false;
}
//check axis link
QString errmsg;
bool hasValidAxisLink = false;
try{
App::PropertyLinkSub lnk;
this->getAxisLink(lnk);
Base::Vector3d dir, base;
hasValidAxisLink = Part::Extrusion::fetchAxisLink(lnk, base, dir);
} catch(Base::Exception &err) {
errmsg = QCoreApplication::translate("Exception", err.what());
} catch(Standard_Failure &err) {
errmsg = QString::fromLocal8Bit(err.GetMessageString());
} catch(...) {
errmsg = tr("Unknown error");
}
if (this->getDirMode() == Part::Extrusion::dmEdge && !hasValidAxisLink){
if (errmsg.length() > 0)
QMessageBox::critical(this, windowTitle(), tr("Extrusion direction link is invalid.\n\n%1").arg(errmsg));
else
QMessageBox::critical(this, windowTitle(), tr("Direction mode is to use an edge, but no edge is linked."));
ui->txtLink->setFocus();
return false;
} else if (this->getDirMode() != Part::Extrusion::dmEdge && !hasValidAxisLink){
//axis link is invalid, but it is not required by the mode. We shouldn't complain it's invalid then...
ui->txtLink->clear();
}
//check normal
if (this->getDirMode() == Part::Extrusion::dmNormal){
errmsg.clear();
try {
App::PropertyLink lnk;
lnk.setValue(&this->getShapeToExtrude()); //simplified - check only for the first shape.
Part::Extrusion::calculateShapeNormal(lnk);
} catch(Base::Exception &err) {
errmsg = QCoreApplication::translate("Exception", err.what());
} catch(Standard_Failure &err) {
errmsg = QString::fromLocal8Bit(err.GetMessageString());
} catch(...) {
errmsg = QString::fromUtf8("Unknown error");
}
if (errmsg.length() > 0){
QMessageBox::critical(this, windowTitle(), tr("Can't determine normal vector of shape to be extruded. Please use other mode. \n\n(%1)").arg(errmsg));
ui->rbDirModeNormal->setFocus();
return false;
}
}
//check axis dir
if (this->getDirMode() == Part::Extrusion::dmCustom){
if(this->getDir().Length() < Precision::Confusion()){
QMessageBox::critical(this, windowTitle(),
tr("Extrusion direction vector is zero-length. It must be non-zero."));
ui->dirX->setFocus();
return false;
}
}
//check lengths
if (!ui->chkSymmetric->isChecked()
&& fabs(ui->spinLenFwd->value().getValue() + ui->spinLenRev->value().getValue()) < Precision::Confusion()
&& ! (fabs(ui->spinLenFwd->value().getValue() - ui->spinLenRev->value().getValue()) < Precision::Confusion())){
QMessageBox::critical(this, windowTitle(),
tr("Total extrusion length is zero (length1 == -length2). It must be nonzero."));
ui->spinLenFwd->setFocus();
return false;
}
return true;
}
void DlgExtrusion::writeParametersToFeature(App::DocumentObject &feature, App::DocumentObject* base) const
{
Gui::Command::doCommand(Gui::Command::Doc,"f = App.getDocument('%s').getObject('%s')", feature.getDocument()->getName(), feature.getNameInDocument());
if (base)
Gui::Command::doCommand(Gui::Command::Doc,"f.Base = App.getDocument('%s').getObject('%s')", base->getDocument()->getName(), base->getNameInDocument());
Part::Extrusion::eDirMode dirMode = this->getDirMode();
const char* modestr = Part::Extrusion::eDirModeStrings[dirMode];
Gui::Command::doCommand(Gui::Command::Doc,"f.DirMode = \"%s\"", modestr);
if (dirMode == Part::Extrusion::dmCustom){
Base::Vector3d dir = this->getDir();
Gui::Command::doCommand(Gui::Command::Doc, "f.Dir = App.Vector(%.15f, %.15f, %.15f)", dir.x, dir.y, dir.z);
}
App::PropertyLinkSub lnk;
this->getAxisLink(lnk);
std::stringstream linkstr;
if (!lnk.getValue()) {
linkstr << "None";
} else {
linkstr << "(App.getDocument(\"" << lnk.getValue()->getDocument()->getName() <<"\")." << lnk.getValue()->getNameInDocument();
linkstr << ", [";
for (const std::string &str: lnk.getSubValues()){
linkstr << "\"" << str << "\"";
}
linkstr << "])";
}
Gui::Command::doCommand(Gui::Command::Doc,"f.DirLink = %s", linkstr.str().c_str());
Gui::Command::doCommand(Gui::Command::Doc,"f.LengthFwd = %.15f", ui->spinLenFwd->value().getValue());
Gui::Command::doCommand(Gui::Command::Doc,"f.LengthRev = %.15f", ui->spinLenRev->value().getValue());
Gui::Command::doCommand(Gui::Command::Doc,"f.Solid = %s", ui->chkSolid->isChecked() ? "True" : "False");
Gui::Command::doCommand(Gui::Command::Doc,"f.Reversed = %s", ui->chkReversed->isChecked() ? "True" : "False");
Gui::Command::doCommand(Gui::Command::Doc,"f.Symmetric = %s", ui->chkSymmetric->isChecked() ? "True" : "False");
Gui::Command::doCommand(Gui::Command::Doc,"f.TaperAngle = %.15f", ui->spinTaperAngle->value().getValue());
Gui::Command::doCommand(Gui::Command::Doc,"f.TaperAngleRev = %.15f", ui->spinTaperAngleRev->value().getValue());
}
// ---------------------------------------
TaskExtrusion::TaskExtrusion()
{
widget = new DlgExtrusion();
addTaskBox(Gui::BitmapFactory().pixmap("Part_Extrude"), widget);
}
bool TaskExtrusion::accept()
{
widget->accept();
return (widget->result() == QDialog::Accepted);
}
bool TaskExtrusion::reject()
{
widget->reject();
return true;
}
void TaskExtrusion::clicked(int id)
{
if (id == QDialogButtonBox::Apply) {
try{
widget->apply();
} catch (Base::AbortException&){
};
}
}
#include "moc_DlgExtrusion.cpp"