Improved algorithm to detect intersections of rotation axis and sketch

This commit is contained in:
wmayer 2012-12-06 13:21:10 +01:00
parent 6455c4edad
commit f9cff4c8a2

View File

@ -60,6 +60,9 @@
# include <Standard_Version.hxx>
#endif
#include <BRepExtrema_DistShapeShape.hxx>
#include <TopExp.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include "FeatureSketchBased.h"
#include <Mod/Part/App/Part2DObject.h>
@ -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)