DlgExtrusion.cpp
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
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); 
00060     findShapes();
00061 
00062     Gui::ItemViewSelection sel(ui->treeWidget);
00063     sel.applyFrom(Gui::Selection().getObjectsOfType(Part::Feature::getClassTypeId()));
00064 }
00065 
00066 
00067 
00068 
00069 DlgExtrusion::~DlgExtrusion()
00070 {
00071     
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         
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         
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                     
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     
00227     
00228     
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     
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"