diff --git a/src/Mod/TechDraw/App/DrawComplexSection.cpp b/src/Mod/TechDraw/App/DrawComplexSection.cpp index 802ae65c35..ebef5f651f 100644 --- a/src/Mod/TechDraw/App/DrawComplexSection.cpp +++ b/src/Mod/TechDraw/App/DrawComplexSection.cpp @@ -299,7 +299,7 @@ TopoDS_Shape DrawComplexSection::getShapeToPrepare() const //get the shape ready for projection and cut surface finding TopoDS_Shape DrawComplexSection::prepareShape(const TopoDS_Shape &cutShape, double shapeSize) { - // Base::Console().Message("DCS::prepareShape() - strat: %d\n", ProjectionStrategy.getValue()); +// Base::Console().Message("DCS::prepareShape() - strat: %d\n", ProjectionStrategy.getValue()); if (ProjectionStrategy.getValue() == 0) { //Offset. Use regular section behaviour return DrawViewSection::prepareShape(cutShape, shapeSize); @@ -321,7 +321,7 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape, const TopoDS_Shape &toolFaceShape, double extrudeDistance) { - // Base::Console().Message("DCS::makeAlignedPieces()\n"); +// Base::Console().Message("DCS::makeAlignedPieces()\n"); std::vector pieces; std::vector pieceXSize;//size in sectionCS.XDirection (width) std::vector pieceYSize;//size in sectionCS.Direction (depth) @@ -369,7 +369,6 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape, gp_Vec rotateAxis = getSectionCS().Direction().Crossed(gProfileVec); - //make a tool for each segment of the toolFaceShape and intersect it with the //raw shape TopExp_Explorer expFaces(toolFaceShape, TopAbs_FACE); @@ -390,8 +389,9 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape, BRepPrimAPI_MakePrism mkPrism(face, extrudeDir); TopoDS_Shape segmentTool = mkPrism.Shape(); TopoDS_Shape intersect = shapeShapeIntersect(segmentTool, rawShape); - - gp_Pnt pieceCentroid = findCentroid(intersect); + if (intersect.IsNull()) { + continue; + } double faceAngle = gp_Vec(getSectionCS().Direction().Reversed()).AngleWithRef(segmentNormal, rotateAxis); @@ -402,7 +402,6 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape, TopoDS_Shape pieceCentered = mkTransXLate.Shape(); //rotate the intersection so interesting face is aligned with paper plane - pieceCentroid = findCentroid(pieceCentered); gp_Ax1 faceAxis(gp_Pnt(0.0, 0.0, 0.0), rotateAxis); gp_Ax3 pieceCS;//XYZ tipped so face is aligned with sectionCS pieceCS.Rotate(faceAxis, faceAngle); @@ -516,7 +515,7 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape, TopoDS_Compound DrawComplexSection::findSectionPlaneIntersections(const TopoDS_Shape &shapeToIntersect) { - // Base::Console().Message("DCS::findSectionPlaneIntersections() - %s\n", getNameInDocument()); +// Base::Console().Message("DCS::findSectionPlaneIntersections() - %s\n", getNameInDocument()); if (shapeToIntersect.IsNull()) { // this shouldn't happen Base::Console().Warning("DCS::findSectionPlaneInter - %s - cut shape is Null\n", @@ -527,7 +526,7 @@ DrawComplexSection::findSectionPlaneIntersections(const TopoDS_Shape &shapeToInt return singleToolIntersections(shapeToIntersect); } - return piecewiseToolIntersections(shapeToIntersect); + return alignedToolIntersections(shapeToIntersect); } //Intersect cutShape with each segment of the cutting tool @@ -566,9 +565,9 @@ TopoDS_Compound DrawComplexSection::singleToolIntersections(const TopoDS_Shape & } //Intersect cutShape with the effective (flattened) cutting plane to generate cut surface faces -TopoDS_Compound DrawComplexSection::piecewiseToolIntersections(const TopoDS_Shape &cutShape) +TopoDS_Compound DrawComplexSection::alignedToolIntersections(const TopoDS_Shape &cutShape) { - // Base::Console().Message("DCS::piecewiseToolIntersections()\n"); +// Base::Console().Message("DCS::alignedToolIntersections()\n"); BRep_Builder builder; TopoDS_Compound result; builder.MakeCompound(result); @@ -576,11 +575,11 @@ TopoDS_Compound DrawComplexSection::piecewiseToolIntersections(const TopoDS_Shap App::DocumentObject *toolObj = CuttingToolWireObject.getValue(); if (!isLinearProfile(toolObj)) { //TODO: special handling here - // Base::Console().Message("DCS::pieceWiseToolIntersection - profile has curves\n"); + // Base::Console().Message("DCS::alignedToolIntersection - profile has curves\n"); } gp_Pln effectivePlane = getSectionPlane(); - //piecewise result can be much wider than the shape itself, so we use an + //aligned result can be much wider than the shape itself, so we use an //infinite face. BRepBuilderAPI_MakeFace mkFace(effectivePlane, -Precision::Infinite(), Precision::Infinite(), -Precision::Infinite(), Precision::Infinite()); @@ -1037,7 +1036,11 @@ TopoDS_Shape DrawComplexSection::shapeShapeIntersect(const TopoDS_Shape &shape0, anOp.SetArguments(anArg1); anOp.SetTools(anArg2); anOp.Build(); - return anOp.Shape();//always a compound + TopoDS_Shape result = anOp.Shape();//always a compound + if (isTrulyEmpty(result)) { + return TopoDS_Shape(); + } + return result; } //find all the intersecting regions of face and shape @@ -1162,6 +1165,17 @@ bool DrawComplexSection::isLinearProfile(App::DocumentObject *obj) return false; } +//a compound with no content is not considered IsNull by OCC. A more thorough check +//is required. +//https://dev.opencascade.org/content/compound-empty +bool DrawComplexSection::isTrulyEmpty(TopoDS_Shape inShape) +{ + if (!inShape.IsNull() && TopoDS_Iterator(inShape).More()) { + return false; + } + return true; +} + // Python Drawing feature --------------------------------------------------------- namespace App diff --git a/src/Mod/TechDraw/App/DrawComplexSection.h b/src/Mod/TechDraw/App/DrawComplexSection.h index f12b18ec8c..caa8cf1a7c 100644 --- a/src/Mod/TechDraw/App/DrawComplexSection.h +++ b/src/Mod/TechDraw/App/DrawComplexSection.h @@ -88,7 +88,7 @@ public: double extrudeDistance); TopoDS_Shape distributeAlignedPieces(std::vector pieces); TopoDS_Compound singleToolIntersections(const TopoDS_Shape &cutShape); - TopoDS_Compound piecewiseToolIntersections(const TopoDS_Shape &cutShape); + TopoDS_Compound alignedToolIntersections(const TopoDS_Shape &cutShape); BaseGeomPtrVector makeSectionLineGeometry(); std::pair sectionArrowDirs(); @@ -106,6 +106,7 @@ public: static bool isProfileObject(App::DocumentObject *obj); static bool isMultiSegmentProfile(App::DocumentObject *obj); static bool isLinearProfile(App::DocumentObject *obj); + static bool isTrulyEmpty(TopoDS_Shape inShape); private: gp_Dir getFaceNormal(TopoDS_Face &face);