diff --git a/src/Mod/TechDraw/App/DrawViewDetail.cpp b/src/Mod/TechDraw/App/DrawViewDetail.cpp index 1fe3feebf8..95572f6dd4 100644 --- a/src/Mod/TechDraw/App/DrawViewDetail.cpp +++ b/src/Mod/TechDraw/App/DrawViewDetail.cpp @@ -64,6 +64,7 @@ using namespace TechDraw; +using DU = DrawUtil; //=========================================================================== // DrawViewDetail @@ -154,13 +155,13 @@ App::DocumentObjectExecReturn* DrawViewDetail::execute() } DrawViewPart* dvp = static_cast(baseObj); - TopoDS_Shape shape = dvp->getShapeForDetail(); + TopoDS_Shape shape3d = dvp->getShapeForDetail(); DrawViewSection* dvs = nullptr; if (dvp->isDerivedFrom(TechDraw::DrawViewSection::getClassTypeId())) { dvs = static_cast(dvp); } - if (shape.IsNull()) { + if (shape3d.IsNull()) { return DrawView::execute(); } @@ -173,7 +174,7 @@ App::DocumentObjectExecReturn* DrawViewDetail::execute() //unblock } - detailExec(shape, dvp, dvs); + detailExec(shape3d, dvp, dvs); addPoints(); dvp->requestPaint();//to refresh detail highlight in base view @@ -208,7 +209,7 @@ void DrawViewDetail::detailExec(TopoDS_Shape& shape, DrawViewPart* dvp, DrawView //this runs in a separate thread since it can sometimes take a long time //make a common of the input shape and a cylinder (or prism depending on //the matting style) -void DrawViewDetail::makeDetailShape(const TopoDS_Shape& shape, DrawViewPart* dvp, DrawViewSection* dvs) +void DrawViewDetail::makeDetailShape(const TopoDS_Shape& shape3d, DrawViewPart* dvp, DrawViewSection* dvs) { showProgressMessage(getNameInDocument(), "is making detail shape"); @@ -216,7 +217,7 @@ void DrawViewDetail::makeDetailShape(const TopoDS_Shape& shape, DrawViewPart* dv double radius = getFudgeRadius(); //make a copy of the input shape so we don't inadvertently change it - BRepBuilderAPI_Copy BuilderCopy(shape); + BRepBuilderAPI_Copy BuilderCopy(shape3d); TopoDS_Shape copyShape = BuilderCopy.Shape(); m_saveShape = copyShape; m_saveDvp = dvp; @@ -284,15 +285,72 @@ void DrawViewDetail::makeDetailShape(const TopoDS_Shape& shape, DrawViewPart* dv } } - BRepAlgoAPI_Common mkCommon(copyShape, tool); - if (!mkCommon.IsDone() || mkCommon.Shape().IsNull()) { - Base::Console().Warning("DVD::detailExec - %s - failed to create detail shape\n", - getNameInDocument()); - return; + //for each solid and shell in the input shape, make a common with the tool and + //add the result to a compound. This avoids issues with some geometry errors in the + //input shape. + BRep_Builder builder; + TopoDS_Compound pieces; + builder.MakeCompound(pieces); + TopExp_Explorer expl1(copyShape, TopAbs_SOLID); + for (; expl1.More(); expl1.Next()) { + const TopoDS_Solid& s = TopoDS::Solid(expl1.Current()); + BRepAlgoAPI_Common mkCommon(s, tool); + if (!mkCommon.IsDone()) { + continue; + } + if (mkCommon.Shape().IsNull()) { + continue; + } + //Did we get a result? + TopExp_Explorer xp; + xp.Init(mkCommon.Shape(), TopAbs_SOLID); + if (xp.More() != Standard_True) { + continue; + } + builder.Add(pieces, mkCommon.Shape()); + } + + TopExp_Explorer expl2(copyShape, TopAbs_SHELL, TopAbs_SOLID); + for (; expl2.More(); expl2.Next()) { + const TopoDS_Shell& s = TopoDS::Shell(expl2.Current()); + BRepAlgoAPI_Common mkCommon(s, tool); + if (!mkCommon.IsDone()) { + continue; + } + if (mkCommon.Shape().IsNull()) { + continue; + } + //Did we get a result? + TopExp_Explorer xp; + xp.Init(mkCommon.Shape(), TopAbs_SHELL); + if (xp.More() != Standard_True) { + continue; + } + builder.Add(pieces, mkCommon.Shape()); + } + + // now get any loose edges in the input + TopExp_Explorer expl3(copyShape, TopAbs_EDGE, TopAbs_FACE); + for (; expl3.More(); expl3.Next()) { + const TopoDS_Edge& e = TopoDS::Edge(expl3.Current()); + BRepAlgoAPI_Common mkCommon(e, tool); + if (!mkCommon.IsDone()) { + continue; + } + if (mkCommon.Shape().IsNull()) { + continue; + } + //Did we get a result? + TopExp_Explorer xp; + xp.Init(mkCommon.Shape(), TopAbs_EDGE); + if (xp.More() != Standard_True) { + continue; + } + builder.Add(pieces, mkCommon.Shape()); } // save the detail shape for further processing - m_detailShape = mkCommon.Shape(); + m_detailShape = pieces; if (debugDetail()) { BRepTools::Write(tool, "DVDTool.brep"); //debug diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index cdd99747eb..ae10bac894 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -184,7 +184,7 @@ TopoDS_Shape DrawViewPart::getSourceShape(bool fuse) const //! version of the shape? Should we have a getShapeForSection? TopoDS_Shape DrawViewPart::getShapeForDetail() const { - return ShapeUtils::rotateShape(getSourceShape(true), getProjectionCS(), Rotation.getValue()); + return ShapeUtils::rotateShape(getSourceShape(false), getProjectionCS(), Rotation.getValue()); } //! combine the regular links and xlinks into a single list diff --git a/src/Mod/TechDraw/App/ShapeExtractor.cpp b/src/Mod/TechDraw/App/ShapeExtractor.cpp index 2df81c589c..a1c4cdbf77 100644 --- a/src/Mod/TechDraw/App/ShapeExtractor.cpp +++ b/src/Mod/TechDraw/App/ShapeExtractor.cpp @@ -55,7 +55,7 @@ using DU = DrawUtil; using SU = ShapeUtils; -//! pick out the 2d document objects objects in the list of links and return a vector of their shapes +//! pick out the 2d document objects in the list of links and return a vector of their shapes //! Note that point objects will not make it through the hlr/projection process. std::vector ShapeExtractor::getShapes2d(const std::vector links) { @@ -64,28 +64,13 @@ std::vector ShapeExtractor::getShapes2d(const std::vector shapes2d; for (auto& l:links) { - const App::GroupExtension* gex = dynamic_cast(l); - if (gex) { - std::vector groupAll = gex->Group.getValues(); - for (auto& item : groupAll) { - if (is2dObject(item)) { - if (item->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { - TopoDS_Shape temp = getLocatedShape(item); - if (!temp.IsNull()) { - shapes2d.push_back(temp); - } - } + if (is2dObject(l)) { + if (l->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + TopoDS_Shape temp = getLocatedShape(l); + if (!temp.IsNull()) { + shapes2d.push_back(temp); } - } - } else { - if (is2dObject(l)) { - if (l->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { - TopoDS_Shape temp = getLocatedShape(l); - if (!temp.IsNull()) { - shapes2d.push_back(temp); - } - } // other 2d objects would go here - Draft objects? Arch Axis? - } + } // other 2d objects would go here - Draft objects? Arch Axis? } } return shapes2d; @@ -95,11 +80,12 @@ std::vector ShapeExtractor::getShapes2d(const std::vector links, bool include2d) { -// Base::Console().Message("SE::getShapes() - links in: %d\n", links.size()); + // Base::Console().Message("SE::getShapes() - links in: %d\n", links.size()); std::vector sourceShapes; for (auto& l:links) { if (is2dObject(l) && !include2d) { + // Base::Console().Message("SE::getShapes - skipping 2d link: %s\n", l->Label.getValue()); continue; } if (l->isDerivedFrom()) { @@ -111,6 +97,7 @@ TopoDS_Shape ShapeExtractor::getShapes(const std::vector l } } else { auto shape = Part::Feature::getShape(l); + // if link l has a shape, we use that shape. if(!SU::isShapeReallyNull((shape))) { sourceShapes.push_back(getLocatedShape(l)); } else { @@ -327,10 +314,13 @@ TopoDS_Shape ShapeExtractor::getShapesFused(const std::vector shapes2d = getShapes2d(links); + BRepTools::Write(DrawUtil::shapeVectorToCompound(shapes2d, false), "SEshapes2d.brep"); + if (!shapes2d.empty()) { shapes2d.push_back(baseShape); return DrawUtil::shapeVectorToCompound(shapes2d, false);