diff --git a/src/Mod/Part/App/PartFeatures.cpp b/src/Mod/Part/App/PartFeatures.cpp index 5c9a081c5..bdcdebb0d 100644 --- a/src/Mod/Part/App/PartFeatures.cpp +++ b/src/Mod/Part/App/PartFeatures.cpp @@ -31,9 +31,11 @@ # include # include # include +# include # include # include # include +# include # include # include # include @@ -339,14 +341,14 @@ App::DocumentObjectExecReturn *Sweep::execute(void) const Part::TopoShape& shape = static_cast(spine)->Shape.getValue(); if (!shape._Shape.IsNull()) { try { - BRepBuilderAPI_MakeWire mkWire; - for (std::vector::const_iterator it = subedge.begin(); it != subedge.end(); ++it) { - TopoDS_Shape subshape = shape.getSubShape(it->c_str()); - mkWire.Add(TopoDS::Edge(subshape)); + if (!subedge.empty()) { + BRepBuilderAPI_MakeWire mkWire; + for (std::vector::const_iterator it = subedge.begin(); it != subedge.end(); ++it) { + TopoDS_Shape subshape = shape.getSubShape(it->c_str()); + mkWire.Add(TopoDS::Edge(subshape)); + } + path = mkWire.Wire(); } - path = mkWire.Wire(); - } - catch (Standard_Failure) { if (shape._Shape.ShapeType() == TopAbs_EDGE) { path = shape._Shape; } @@ -354,10 +356,35 @@ App::DocumentObjectExecReturn *Sweep::execute(void) BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape)); path = mkWire.Wire(); } + else if (shape._Shape.ShapeType() == TopAbs_COMPOUND) { + TopoDS_Iterator it(shape._Shape); + for (; it.More(); it.Next()) { + if (it.Value().IsNull()) + return new App::DocumentObjectExecReturn("In valid element in spine."); + if ((it.Value().ShapeType() != TopAbs_EDGE) && + (it.Value().ShapeType() != TopAbs_WIRE)) { + return new App::DocumentObjectExecReturn("Element in spine is neither an edge nor a wire."); + } + } + + Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape(); + Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape(); + for (TopExp_Explorer xp(shape._Shape, TopAbs_EDGE); xp.More(); xp.Next()) + hEdges->Append(xp.Current()); + + ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_True, hWires); + int len = hWires->Length(); + if (len != 1) + return new App::DocumentObjectExecReturn("Spine is not connected."); + path = hWires->Value(1); + } else { return new App::DocumentObjectExecReturn("Spine is neither an edge nor a wire."); } } + catch (Standard_Failure) { + return new App::DocumentObjectExecReturn("Invalid spine."); + } } try { diff --git a/src/Mod/Part/App/TopoShapeCompoundPy.xml b/src/Mod/Part/App/TopoShapeCompoundPy.xml index eebec76d5..2439bfc7f 100644 --- a/src/Mod/Part/App/TopoShapeCompoundPy.xml +++ b/src/Mod/Part/App/TopoShapeCompoundPy.xml @@ -19,7 +19,7 @@ Add a shape to the compound. - + Build a compound of wires out of the edges of this compound. diff --git a/src/Mod/Part/Gui/TaskSweep.cpp b/src/Mod/Part/Gui/TaskSweep.cpp index e21ea8157..6326f5517 100644 --- a/src/Mod/Part/Gui/TaskSweep.cpp +++ b/src/Mod/Part/Gui/TaskSweep.cpp @@ -28,8 +28,12 @@ # include # include # include +# include +# include +# include # include # include +# include #endif #include "ui_TaskSweep.h" @@ -41,6 +45,7 @@ #include #include #include +#include #include #include @@ -81,10 +86,27 @@ public: // shape is an edge or wire we can use it completely. const TopoDS_Shape& shape = static_cast(pObj)->Shape.getValue(); if (!shape.IsNull()) { - if (shape.ShapeType() == TopAbs_EDGE) + // a single edge + if (shape.ShapeType() == TopAbs_EDGE) { return true; - if (shape.ShapeType() == TopAbs_WIRE) + } + // a single wire + if (shape.ShapeType() == TopAbs_WIRE) { return true; + } + // a compound of only edges or wires + if (shape.ShapeType() == TopAbs_COMPOUND) { + TopoDS_Iterator it(shape); + for (; it.More(); it.Next()) { + if (it.Value().IsNull()) + return false; + if ((it.Value().ShapeType() != TopAbs_EDGE) && + (it.Value().ShapeType() != TopAbs_WIRE)) + return false; + } + + return true; + } } } else { @@ -199,6 +221,30 @@ bool SweepWidget::isPathValid(const Gui::SelectionObject& sel) const BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape)); pathShape = mkWire.Wire(); } + else if (shape._Shape.ShapeType() == TopAbs_COMPOUND) { + try { + TopoDS_Iterator it(shape._Shape); + for (; it.More(); it.Next()) { + if ((it.Value().ShapeType() != TopAbs_EDGE) && + (it.Value().ShapeType() != TopAbs_WIRE)) { + return false; + } + } + Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape(); + Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape(); + for (TopExp_Explorer xp(shape._Shape, TopAbs_EDGE); xp.More(); xp.Next()) + hEdges->Append(xp.Current()); + + ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_True, hWires); + int len = hWires->Length(); + if (len != 1) + return false; + pathShape = hWires->Value(1); + } + catch (...) { + return false; + } + } return (!pathShape.IsNull()); } @@ -255,6 +301,7 @@ bool SweepWidget::accept() } try { + Gui::WaitCursor wc; QString cmd; cmd = QString::fromAscii( "App.getDocument('%5').addObject('Part::Sweep','Sweep')\n"