Merge pull request #19843 from Shkolik/sketcher_spline_intersection

fix #19831 Sketcher: Create external Intersection geometry not working with complex surfaces
This commit is contained in:
Chris Hennes
2025-03-11 21:44:28 +00:00
committed by GitHub

View File

@@ -8977,16 +8977,58 @@ 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())) {
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();
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.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);
}
}