DlgExtrusion.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2008 Werner Mayer <wmayer[at]users.sourceforge.net>     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 # include <BRepAdaptor_Surface.hxx>
00027 # include <BRepLProp_SLProps.hxx>
00028 # include <BRepGProp_Face.hxx>
00029 # include <Precision.hxx>
00030 # include <TopoDS.hxx>
00031 # include <TopoDS_Face.hxx>
00032 # include <TopExp_Explorer.hxx>
00033 # include <QMessageBox>
00034 #endif
00035 
00036 #include "ui_DlgExtrusion.h"
00037 #include "DlgExtrusion.h"
00038 #include "../App/PartFeature.h"
00039 #include <Base/Console.h>
00040 #include <App/Application.h>
00041 #include <App/Document.h>
00042 #include <App/DocumentObject.h>
00043 #include <Gui/Application.h>
00044 #include <Gui/BitmapFactory.h>
00045 #include <Gui/Command.h>
00046 #include <Gui/Document.h>
00047 #include <Gui/ViewProvider.h>
00048 #include <Gui/WaitCursor.h>
00049 #include <Gui/Utilities.h>
00050 
00051 using namespace PartGui;
00052 
00053 DlgExtrusion::DlgExtrusion(QWidget* parent, Qt::WFlags fl)
00054   : QDialog(parent, fl), ui(new Ui_DlgExtrusion)
00055 {
00056     ui->setupUi(this);
00057     ui->labelNormal->hide();
00058     ui->viewButton->hide();
00059     ui->dirLen->setMinimumWidth(55); // needed to show all digits
00060     findShapes();
00061 
00062     Gui::ItemViewSelection sel(ui->treeWidget);
00063     sel.applyFrom(Gui::Selection().getObjectsOfType(Part::Feature::getClassTypeId()));
00064 }
00065 
00066 /*  
00067  *  Destroys the object and frees any allocated resources
00068  */
00069 DlgExtrusion::~DlgExtrusion()
00070 {
00071     // no need to delete child widgets, Qt does it all for us
00072     delete ui;
00073 }
00074 
00075 void DlgExtrusion::changeEvent(QEvent *e)
00076 {
00077     if (e->type() == QEvent::LanguageChange) {
00078         ui->retranslateUi(this);
00079     }
00080     QDialog::changeEvent(e);
00081 }
00082 
00083 void DlgExtrusion::findShapes()
00084 {
00085     App::Document* activeDoc = App::GetApplication().getActiveDocument();
00086     if (!activeDoc) return;
00087     Gui::Document* activeGui = Gui::Application::Instance->getDocument(activeDoc);
00088     this->document = activeDoc->getName();
00089     this->label = activeDoc->Label.getValue();
00090 
00091     std::vector<App::DocumentObject*> objs = activeDoc->getObjectsOfType
00092         (Part::Feature::getClassTypeId());
00093     for (std::vector<App::DocumentObject*>::iterator it = objs.begin(); it!=objs.end(); ++it) {
00094         const TopoDS_Shape& shape = static_cast<Part::Feature*>(*it)->Shape.getValue();
00095         if (canExtrude(shape)) {
00096             QTreeWidgetItem* item = new QTreeWidgetItem(ui->treeWidget);
00097             item->setText(0, QString::fromUtf8((*it)->Label.getValue()));
00098             item->setData(0, Qt::UserRole, QString::fromAscii((*it)->getNameInDocument()));
00099             Gui::ViewProvider* vp = activeGui->getViewProvider(*it);
00100             if (vp)
00101                 item->setIcon(0, vp->getIcon());
00102         }
00103     }
00104 }
00105 
00106 bool DlgExtrusion::canExtrude(const TopoDS_Shape& shape) const
00107 {
00108     if (shape.IsNull())
00109         return false;
00110     TopAbs_ShapeEnum type = shape.ShapeType();
00111     if (type == TopAbs_VERTEX || type == TopAbs_EDGE ||
00112         type == TopAbs_WIRE || type == TopAbs_FACE ||
00113         type == TopAbs_SHELL)
00114         return true;
00115     if (type == TopAbs_COMPOUND) {
00116         TopExp_Explorer xp;
00117         xp.Init(shape,TopAbs_SOLID);
00118         while (xp.More()) {
00119             return false;
00120         }
00121         xp.Init(shape,TopAbs_COMPSOLID);
00122         while (xp.More()) {
00123             return false;
00124         }
00125 
00126         return true;
00127     }
00128 
00129     return false;
00130 }
00131 
00132 void DlgExtrusion::accept()
00133 {
00134     apply();
00135     QDialog::accept();
00136 }
00137 
00138 void DlgExtrusion::apply()
00139 {
00140     if (ui->treeWidget->selectedItems().isEmpty()) {
00141         QMessageBox::critical(this, windowTitle(), 
00142             tr("Select a shape for extrusion, first."));
00143         return;
00144     }
00145 
00146     Gui::WaitCursor wc;
00147     App::Document* activeDoc = App::GetApplication().getDocument(this->document.c_str());
00148     if (!activeDoc) {
00149         QMessageBox::critical(this, windowTitle(), 
00150             tr("The document '%1' doesn't exist.").arg(QString::fromUtf8(this->label.c_str())));
00151         return;
00152     }
00153     activeDoc->openTransaction("Extrude");
00154 
00155     QString shape, type, name;
00156     QList<QTreeWidgetItem *> items = ui->treeWidget->selectedItems();
00157     for (QList<QTreeWidgetItem *>::iterator it = items.begin(); it != items.end(); ++it) {
00158         shape = (*it)->data(0, Qt::UserRole).toString();
00159         type = QString::fromAscii("Part::Extrusion");
00160         name = QString::fromAscii(activeDoc->getUniqueObjectName("Extrude").c_str());
00161         double len = ui->dirLen->value();
00162         double dirX = ui->dirX->value();
00163         double dirY = ui->dirY->value();
00164         double dirZ = ui->dirZ->value();
00165 
00166         // inspect geometry
00167         App::DocumentObject* obj = activeDoc->getObject((const char*)shape.toAscii());
00168         if (!obj || !obj->isDerivedFrom(Part::Feature::getClassTypeId())) continue;
00169         Part::Feature* fea = static_cast<Part::Feature*>(obj);
00170         const TopoDS_Shape& data = fea->Shape.getValue();
00171         if (data.IsNull()) continue;
00172 
00173         // check for planes
00174         if (ui->checkNormal->isChecked() && data.ShapeType() == TopAbs_FACE) {
00175             BRepAdaptor_Surface adapt(TopoDS::Face(data));
00176             if (adapt.GetType() == GeomAbs_Plane) {
00177                 double u = 0.5*(adapt.FirstUParameter() + adapt.LastUParameter());
00178                 double v = 0.5*(adapt.FirstVParameter() + adapt.LastVParameter());
00179                 BRepLProp_SLProps prop(adapt,u,v,1,Precision::Confusion());
00180                 if (prop.IsNormalDefined()) {
00181                     gp_Pnt pnt; gp_Vec vec;
00182                     // handles the orientation state of the shape
00183                     BRepGProp_Face(TopoDS::Face(data)).Normal(u,v,pnt,vec);
00184                     dirX = vec.X();
00185                     dirY = vec.Y();
00186                     dirZ = vec.Z();
00187                 }
00188             }
00189         }
00190 
00191         QString code = QString::fromAscii(
00192             "FreeCAD.getDocument(\"%1\").addObject(\"%2\",\"%3\")\n"
00193             "FreeCAD.getDocument(\"%1\").%3.Base = FreeCAD.getDocument(\"%1\").%4\n"
00194             "FreeCAD.getDocument(\"%1\").%3.Dir = (%5,%6,%7)\n"
00195             "FreeCADGui.getDocument(\"%1\").%4.Visibility = False\n")
00196             .arg(QString::fromAscii(this->document.c_str()))
00197             .arg(type).arg(name).arg(shape)
00198             .arg(dirX*len)
00199             .arg(dirY*len)
00200             .arg(dirZ*len);
00201         Gui::Application::Instance->runPythonCode((const char*)code.toAscii());
00202         QByteArray to = name.toAscii();
00203         QByteArray from = shape.toAscii();
00204         Gui::Command::copyVisual(to, "ShapeColor", from);
00205         Gui::Command::copyVisual(to, "LineColor", from);
00206         Gui::Command::copyVisual(to, "PointColor", from);
00207     }
00208 
00209     activeDoc->commitTransaction();
00210     try {
00211         activeDoc->recompute();
00212     }
00213     catch (const std::exception& e) {
00214         Base::Console().Error("%s\n", e.what());
00215     }
00216     catch (const Base::Exception& e) {
00217         Base::Console().Error("%s\n", e.what());
00218     }
00219     catch (...) {
00220         Base::Console().Error("General error while extruding\n");
00221     }
00222 }
00223 
00224 void DlgExtrusion::on_checkNormal_toggled(bool b)
00225 {
00226     //ui->dirX->setDisabled(b);
00227     //ui->dirY->setDisabled(b);
00228     //ui->dirZ->setDisabled(b);
00229     ui->labelNormal->setVisible(b);
00230 }
00231 
00232 // ---------------------------------------
00233 
00234 TaskExtrusion::TaskExtrusion()
00235 {
00236     widget = new DlgExtrusion();
00237     taskbox = new Gui::TaskView::TaskBox(
00238         Gui::BitmapFactory().pixmap("Part_Extrude"),
00239         widget->windowTitle(), true, 0);
00240     taskbox->groupLayout()->addWidget(widget);
00241     Content.push_back(taskbox);
00242 }
00243 
00244 TaskExtrusion::~TaskExtrusion()
00245 {
00246     // automatically deleted in the sub-class
00247 }
00248 
00249 bool TaskExtrusion::accept()
00250 {
00251     widget->accept();
00252     return (widget->result() == QDialog::Accepted);
00253 }
00254 
00255 void TaskExtrusion::clicked(int id)
00256 {
00257     if (id == QDialogButtonBox::Apply) {
00258         widget->apply();
00259     }
00260 }
00261 
00262 #include "moc_DlgExtrusion.cpp"

Generated on Wed Nov 23 19:00:06 2011 for FreeCAD by  doxygen 1.6.1