From db78be8e59e04c2cebcb8f58e6cb46e607b5e22b Mon Sep 17 00:00:00 2001 From: Andrew Shkolik Date: Tue, 25 Feb 2025 01:27:58 -0600 Subject: [PATCH 1/3] fix #19831 Sketcher: Create external Intersection geometry not working with complex surfaces Co-authored-by: Zheng Lei --- src/Mod/Sketcher/App/SketchObject.cpp | 43 ++++++++++++++++++++------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index e881eee5e4..0c421f785e 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -8960,16 +8960,39 @@ void processEdge(const TopoDS_Edge& edge, } else { try { - BRepOffsetAPI_NormalProjection mkProj(aProjFace); - mkProj.Add(edge); - mkProj.Build(); - const TopoDS_Shape& projShape = mkProj.Projection(); - if (!projShape.IsNull()) { - TopExp_Explorer xp; - for (xp.Init(projShape, TopAbs_EDGE); xp.More(); xp.Next()) { - TopoDS_Edge projEdge = TopoDS::Edge(xp.Current()); - TopLoc_Location loc(mov); - projEdge.Location(loc); + Part::TopoShape projShape; + // Projection of the edge on parallel plane to the sketch plane is edge itself + // all we need to do is match coordinate systems + // for some reason OCC doesn't like to project a planar B-Spline to a plane parallel to it + if (planar && plane.Axis().Direction().IsParallel(sketchPlane.Axis().Direction(), Precision::Confusion())) { + // We can't use gp_Pln::Distance() because we need to + // know which side the plane is regarding the sketch + const gp_Pnt& aP = sketchPlane.Location(); + const gp_Pnt& aLoc = plane.Location (); + const gp_Dir& aDir = plane.Axis().Direction(); + double d = (aDir.X() * (aP.X() - aLoc.X()) + + aDir.Y() * (aP.Y() - aLoc.Y()) + + aDir.Z() * (aP.Z() - aLoc.Z())); + + gp_Trsf trsf; + trsf.SetTranslation(gp_Vec(aDir) * d); + projShape.setShape(edge); + projShape.transformShape(Part::TopoShape::convert(trsf), /*copy*/false); + + } else { + // When planes not parallel or perpendicular, or edge is not planar + // normal projection is working just fine + BRepOffsetAPI_NormalProjection mkProj(aProjFace); + mkProj.Add(edge); + mkProj.Build(); + + projShape.setShape(mkProj.Projection()); + } + if (!projShape.isNull() && projShape.hasSubShape(TopAbs_EDGE)) { + for (auto &e : projShape.getSubTopoShapes(TopAbs_EDGE)) { + // Transform copy of the edge to the sketch plane local coordinates + e.transformShape(invPlm.toMatrix(), /*copy*/true, /*checkScale*/true); + TopoDS_Edge projEdge = TopoDS::Edge(e.getShape()); processEdge2(projEdge, geos); } } From c502fc26d48ee00b90b950b2217a0c89c4028be9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 07:45:11 +0000 Subject: [PATCH 2/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/Mod/Sketcher/App/SketchObject.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 0c421f785e..5ef469de8e 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -8973,7 +8973,7 @@ void processEdge(const TopoDS_Edge& edge, double d = (aDir.X() * (aP.X() - aLoc.X()) + aDir.Y() * (aP.Y() - aLoc.Y()) + aDir.Z() * (aP.Z() - aLoc.Z())); - + gp_Trsf trsf; trsf.SetTranslation(gp_Vec(aDir) * d); projShape.setShape(edge); @@ -8985,7 +8985,7 @@ void processEdge(const TopoDS_Edge& edge, BRepOffsetAPI_NormalProjection mkProj(aProjFace); mkProj.Add(edge); mkProj.Build(); - + projShape.setShape(mkProj.Projection()); } if (!projShape.isNull() && projShape.hasSubShape(TopAbs_EDGE)) { From 90198413e7fe6523c550f52f62a7b9cc215ed30e Mon Sep 17 00:00:00 2001 From: Andrew Shkolik Date: Fri, 28 Feb 2025 12:33:56 -0600 Subject: [PATCH 3/3] fixes #19831 - additional code to cover projection of split curve edge --- src/Mod/Sketcher/App/SketchObject.cpp | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 0c421f785e..5716f9a818 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -8965,6 +8965,27 @@ void processEdge(const TopoDS_Edge& edge, // all we need to do is match coordinate systems // for some reason OCC doesn't like to project a planar B-Spline to a plane parallel to it if (planar && plane.Axis().Direction().IsParallel(sketchPlane.Axis().Direction(), Precision::Confusion())) { + TopoDS_Edge projEdge = edge; + + // We need to trim the curve in case we are projecting a B-Spline segment + if(curve.GetType() == GeomAbs_BSplineCurve){ + double Param1 = curve.FirstParameter(); + double Param2 = curve.LastParameter(); + + if (Param1 > Param2){ + std::swap(Param1, Param2); + } + + // trim curve in case we are projecting a segment + auto bsplineCurve = curve.BSpline(); + if(Param2 - Param1 > Precision::Confusion()){ + bsplineCurve->Segment(Param1, Param2); + projEdge = BRepBuilderAPI_MakeEdge(bsplineCurve).Edge(); + } + } + + projShape.setShape(projEdge); + // We can't use gp_Pln::Distance() because we need to // know which side the plane is regarding the sketch const gp_Pnt& aP = sketchPlane.Location(); @@ -8973,12 +8994,10 @@ void processEdge(const TopoDS_Edge& edge, double d = (aDir.X() * (aP.X() - aLoc.X()) + aDir.Y() * (aP.Y() - aLoc.Y()) + aDir.Z() * (aP.Z() - aLoc.Z())); - + gp_Trsf trsf; trsf.SetTranslation(gp_Vec(aDir) * d); - projShape.setShape(edge); projShape.transformShape(Part::TopoShape::convert(trsf), /*copy*/false); - } else { // When planes not parallel or perpendicular, or edge is not planar // normal projection is working just fine