From 03b63d3a407914d8ecc2026f4f005e7a08fda1ad Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 9 Sep 2017 15:59:38 +0200 Subject: [PATCH] make ruled surface working when both curves references the same part and a placement is set --- src/Mod/Part/App/PartFeatures.cpp | 38 +++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/Mod/Part/App/PartFeatures.cpp b/src/Mod/Part/App/PartFeatures.cpp index f1ab818c0c..5f1238473d 100644 --- a/src/Mod/Part/App/PartFeatures.cpp +++ b/src/Mod/Part/App/PartFeatures.cpp @@ -135,6 +135,21 @@ App::DocumentObjectExecReturn *RuledSurface::execute(void) if (S2.ShapeType() != TopAbs_EDGE && S2.ShapeType() != TopAbs_WIRE) return new App::DocumentObjectExecReturn("Linked shape is neither edge nor wire."); + // https://forum.freecadweb.org/viewtopic.php?f=8&t=24052 + // + // if both shapes are sub-elements of one common shape then the fill algorithm + // leads to problems if the shape has set a placement + // The workaround is to reset the placement before calling BRepFill and then + // applying the placement to the output shape + TopLoc_Location Loc; + if (Curve1.getValue() == Curve2.getValue()) { + Loc = S1.Location(); + if (!Loc.IsIdentity() && Loc == S2.Location()) { + S1.Location(TopLoc_Location()); + S2.Location(TopLoc_Location()); + } + } + // make both shapes to have the same type Standard_Boolean isWire = Standard_False; if (S1.ShapeType() == TopAbs_WIRE) @@ -205,14 +220,29 @@ App::DocumentObjectExecReturn *RuledSurface::execute(void) S2.Reverse(); } + TopoDS_Shape ruledShape; if (!isWire) { - TopoDS_Face face = BRepFill::Face(TopoDS::Edge(S1), TopoDS::Edge(S2)); - this->Shape.setValue(face); + ruledShape = BRepFill::Face(TopoDS::Edge(S1), TopoDS::Edge(S2)); } else { - TopoDS_Shell shell = BRepFill::Shell(TopoDS::Wire(S1), TopoDS::Wire(S2)); - this->Shape.setValue(shell); + ruledShape = BRepFill::Shell(TopoDS::Wire(S1), TopoDS::Wire(S2)); } + + // re-apply the placement in case we reset it + if (!Loc.IsIdentity()) + ruledShape.Move(Loc); + Loc = ruledShape.Location(); + + if (!Loc.IsIdentity()) { + // reset the placement of the shape because the Placement + // property will be changed + ruledShape.Location(TopLoc_Location()); + Base::Matrix4D transform; + TopoShape::convertToMatrix(Loc.Transformation(), transform); + this->Placement.setValue(Base::Placement(transform)); + } + + this->Shape.setValue(ruledShape); return App::DocumentObject::StdReturn; } catch (Standard_Failure& e) {