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"