From f9cff4c8a203c3e9cc573ea8360c862afe9d0f56 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 6 Dec 2012 13:21:10 +0100 Subject: [PATCH] Improved algorithm to detect intersections of rotation axis and sketch --- src/Mod/PartDesign/App/FeatureSketchBased.cpp | 76 ++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.cpp b/src/Mod/PartDesign/App/FeatureSketchBased.cpp index 6d2fb9b3b..7ee871768 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.cpp +++ b/src/Mod/PartDesign/App/FeatureSketchBased.cpp @@ -60,6 +60,9 @@ # include #endif +#include +#include +#include #include "FeatureSketchBased.h" #include @@ -538,7 +541,77 @@ const bool SketchBased::checkWireInsideFace(const TopoDS_Wire& wire, const TopoD return (proj.More() && proj.Current().Closed()); } -const bool SketchBased::checkLineCrossesFace(const gp_Lin &line, const TopoDS_Face &face) { +const bool SketchBased::checkLineCrossesFace(const gp_Lin &line, const TopoDS_Face &face) +{ +#if 1 + BRepBuilderAPI_MakeEdge mkEdge(line); + TopoDS_Wire wire = ShapeAnalysis::OuterWire(face); + BRepExtrema_DistShapeShape distss(wire, mkEdge.Shape(), Precision::Confusion()); + if (distss.IsDone()) { + // build up map vertex->edge + TopTools_IndexedDataMapOfShapeListOfShape vertex2Edge; + TopExp::MapShapesAndAncestors(wire, TopAbs_VERTEX, TopAbs_EDGE, vertex2Edge); + + for (Standard_Integer i=1; i<= distss.NbSolution(); i++) { + BRepExtrema_SupportType type = distss.SupportTypeShape1(i); + if (type == BRepExtrema_IsOnEdge) { + //This further check is not really needed + return true; + // + TopoDS_Edge edge = TopoDS::Edge(distss.SupportOnShape1(i)); + BRepAdaptor_Curve adapt(edge); + Standard_Real t; + distss.ParOnEdgeS1(i, t); + if (t > adapt.FirstParameter() && t < adapt.LastParameter()) { + return true; + } + } + else if (type == BRepExtrema_IsVertex) { + // for a vertex check the two adjacent edges if there is a change of sign + TopoDS_Vertex vertex = TopoDS::Vertex(distss.SupportOnShape1(i)); + const TopTools_ListOfShape& edges = vertex2Edge.FindFromKey(vertex); + if (edges.Extent() == 2) { + // create a plane (pnt,dir) that goes through the intersection point and is built of + // the vectors of the sketch normal and the rotation axis + BRepAdaptor_Surface adapt(face); + const gp_Dir& normal = adapt.Plane().Axis().Direction(); + gp_Dir dir = line.Direction().Crossed(normal); + gp_Pnt pnt = distss.PointOnShape1(i); + + // from the first edge get a point next to the intersection point + const TopoDS_Edge& edge1 = TopoDS::Edge(edges.First()); + BRepAdaptor_Curve adapt1(edge1); + Standard_Real dist1 = adapt1.Value(adapt1.FirstParameter()).SquareDistance(pnt); + Standard_Real dist2 = adapt1.Value(adapt1.LastParameter()).SquareDistance(pnt); + gp_Pnt p_eps1; + if (dist1 < dist2) + p_eps1 = adapt1.Value(adapt1.FirstParameter() + 2*Precision::Confusion()); + else + p_eps1 = adapt1.Value(adapt1.LastParameter() - 2*Precision::Confusion()); + + // from the second edge get a point next to the intersection point + const TopoDS_Edge& edge2 = TopoDS::Edge(edges.Last()); + BRepAdaptor_Curve adapt2(edge2); + Standard_Real dist3 = adapt2.Value(adapt2.FirstParameter()).SquareDistance(pnt); + Standard_Real dist4 = adapt2.Value(adapt2.LastParameter()).SquareDistance(pnt); + gp_Pnt p_eps2; + if (dist3 < dist4) + p_eps2 = adapt2.Value(adapt2.FirstParameter() + 2*Precision::Confusion()); + else + p_eps2 = adapt2.Value(adapt2.LastParameter() - 2*Precision::Confusion()); + + // now check if we get a change in the sign of the distances + Standard_Real dist_p_eps1_pnt = gp_Dir(gp_Vec(p_eps1, pnt)).Dot(dir); + Standard_Real dist_p_eps2_pnt = gp_Dir(gp_Vec(p_eps2, pnt)).Dot(dir); + if (dist_p_eps1_pnt * dist_p_eps2_pnt < 0) + return true; + } + } + } + } + + return false; +#else // This is not as easy as it looks, because a distance of zero might be OK if // the axis touches the sketchshape in in a linear edge or a vertex // Note: This algorithm does not catch cases where the sketchshape touches the @@ -595,6 +668,7 @@ const bool SketchBased::checkLineCrossesFace(const gp_Lin &line, const TopoDS_Fa } return false; +#endif } void SketchBased::remapSupportShape(const TopoDS_Shape& newShape)