diff --git a/src/Mod/Part/App/PartFeatures.cpp b/src/Mod/Part/App/PartFeatures.cpp index c50c854bb..1bf2ce874 100644 --- a/src/Mod/Part/App/PartFeatures.cpp +++ b/src/Mod/Part/App/PartFeatures.cpp @@ -28,6 +28,8 @@ # include # include # include +# include +# include #endif @@ -199,6 +201,8 @@ App::DocumentObjectExecReturn *Loft::execute(void) // ---------------------------------------------------------------------------- +const char* Part::Sweep::TransitionEnums[]= {"Transformed","Right corner", "Round corner",NULL}; + PROPERTY_SOURCE(Part::Sweep, Part::Feature) Sweep::Sweep() @@ -207,7 +211,9 @@ Sweep::Sweep() 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"); + ADD_PROPERTY_TYPE(Frenet,(false),"Sweep",App::Prop_None,"Frenet"); + ADD_PROPERTY_TYPE(Transition,(long(0)),"Sweep",App::Prop_None,"Transition mode"); + Transition.setEnums(TransitionEnums); } short Sweep::mustExecute() const @@ -218,7 +224,9 @@ short Sweep::mustExecute() const return 1; if (Solid.isTouched()) return 1; - if (Fresnet.isTouched()) + if (Frenet.isTouched()) + return 1; + if (Transition.isTouched()) return 1; return 0; } @@ -234,22 +242,24 @@ App::DocumentObjectExecReturn *Sweep::execute(void) 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."); + return new App::DocumentObjectExecReturn("No spine linked."); const std::vector& subedge = Spine.getSubValues(); if (subedge.size() != 1) return new App::DocumentObjectExecReturn("Not exactly one sub-shape linked."); - TopoDS_Shape edge; + TopoDS_Shape path; const Part::TopoShape& shape = static_cast(spine)->Shape.getValue(); if (!shape._Shape.IsNull()) { if (!subedge[0].empty()) { - edge = shape.getSubShape(subedge[0].c_str()); + path = shape.getSubShape(subedge[0].c_str()); } else { if (shape._Shape.ShapeType() == TopAbs_EDGE) - edge = shape._Shape; + path = shape._Shape; else if (shape._Shape.ShapeType() == TopAbs_WIRE) - edge = shape._Shape; + path = shape._Shape; + else + return new App::DocumentObjectExecReturn("Spine is neither an edge nor a wire."); } } @@ -279,11 +289,37 @@ App::DocumentObjectExecReturn *Sweep::execute(void) } Standard_Boolean isSolid = Solid.getValue() ? Standard_True : Standard_False; - Standard_Boolean isFresnet = Fresnet.getValue() ? Standard_True : Standard_False; + Standard_Boolean isFrenet = Frenet.getValue() ? Standard_True : Standard_False; + BRepBuilderAPI_TransitionMode transMode; + switch (Transition.getValue()) { + case 1: transMode = BRepBuilderAPI_RightCorner; + break; + case 2: transMode = BRepBuilderAPI_RoundCorner; + break; + default: transMode = BRepBuilderAPI_Transformed; + break; + } - BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(edge)); - TopoShape myShape(mkWire.Wire()); - this->Shape.setValue(myShape.makePipeShell(profiles, isSolid, isFresnet)); + if (path.ShapeType() == TopAbs_EDGE) { + BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(path)); + path = mkWire.Wire(); + } + + BRepOffsetAPI_MakePipeShell mkPipeShell(TopoDS::Wire(path)); + mkPipeShell.SetMode(isFrenet); + mkPipeShell.SetTransitionMode(transMode); + TopTools_ListIteratorOfListOfShape iter; + for (iter.Initialize(profiles); iter.More(); iter.Next()) { + mkPipeShell.Add(TopoDS_Shape(iter.Value())); + } + + if (!mkPipeShell.IsReady()) + Standard_Failure::Raise("shape is not ready to build"); + mkPipeShell.Build(); + if (isSolid) + mkPipeShell.MakeSolid(); + + this->Shape.setValue(mkPipeShell.Shape()); return App::DocumentObject::StdReturn; } catch (Standard_Failure) { diff --git a/src/Mod/Part/App/PartFeatures.h b/src/Mod/Part/App/PartFeatures.h index 25d2050a5..ddaae9627 100644 --- a/src/Mod/Part/App/PartFeatures.h +++ b/src/Mod/Part/App/PartFeatures.h @@ -83,7 +83,8 @@ public: App::PropertyLinkList Sections; App::PropertyLinkSub Spine; App::PropertyBool Solid; - App::PropertyBool Fresnet; + App::PropertyBool Frenet; + App::PropertyEnumeration Transition; /** @name methods override feature */ //@{ @@ -94,6 +95,9 @@ public: protected: void onChanged (const App::Property* prop); + +private: + static const char* TransitionEnums[]; }; } //namespace Part diff --git a/src/Mod/Part/Gui/TaskSweep.cpp b/src/Mod/Part/Gui/TaskSweep.cpp index 0639c28a2..effd5c28b 100644 --- a/src/Mod/Part/Gui/TaskSweep.cpp +++ b/src/Mod/Part/Gui/TaskSweep.cpp @@ -118,25 +118,37 @@ void SweepWidget::findShapes() 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.")); + Gui::SelectionFilter partFilter ("SELECT Part::Feature COUNT 1"); + bool matchEdge = edgeFilter.match(); + bool matchPart = partFilter.match(); + if (!matchEdge && !matchPart) { + QMessageBox::critical(this, tr("Sweep path"), tr("Select an edge or wire you want to sweep along.")); return false; } // get the selected object - const std::vector& result = edgeFilter.Result[0]; - const std::vector& edges = result[0].getSubNames(); + std::string objectName, subShape; + if (matchEdge) { + const std::vector& result = edgeFilter.Result[0]; + const std::vector& edges = result[0].getSubNames(); + objectName = result.front().getFeatName(); + subShape = edges.front(); + } + else { + const std::vector& result = partFilter.Result[0]; + objectName = result.front().getFeatName(); + } - QString list, solid, fresnet; + QString list, solid, frenet; if (d->ui.checkSolid->isChecked()) solid = QString::fromAscii("True"); else solid = QString::fromAscii("False"); - if (d->ui.checkFresnet->isChecked()) - fresnet = QString::fromAscii("True"); + if (d->ui.checkFrenet->isChecked()) + frenet = QString::fromAscii("True"); else - fresnet = QString::fromAscii("False"); + frenet = QString::fromAscii("False"); QTextStream str(&list); @@ -158,11 +170,11 @@ bool SweepWidget::accept() "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" + "App.getDocument('%6').ActiveObject.Frenet=%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())); + .arg(list).arg(QLatin1String(objectName.c_str())) + .arg(QLatin1String(subShape.c_str())) + .arg(solid).arg(frenet).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"); diff --git a/src/Mod/Part/Gui/TaskSweep.ui b/src/Mod/Part/Gui/TaskSweep.ui index f91e754f5..898596365 100644 --- a/src/Mod/Part/Gui/TaskSweep.ui +++ b/src/Mod/Part/Gui/TaskSweep.ui @@ -38,9 +38,9 @@ - + - Fresnet + Frenet