Added check to Revolution and Groove for sketch axis intersecting the sketch face

This commit is contained in:
jrheinlaender 2012-11-30 17:29:07 +04:30 committed by wmayer
parent 8a1c9f0651
commit 8371982dfc
4 changed files with 85 additions and 9 deletions

View File

@ -33,6 +33,7 @@
# include <TopExp_Explorer.hxx> # include <TopExp_Explorer.hxx>
# include <BRepAlgoAPI_Cut.hxx> # include <BRepAlgoAPI_Cut.hxx>
# include <Precision.hxx> # include <Precision.hxx>
# include <gp_Lin.hxx>
#endif #endif
#include <Base/Axis.h> #include <Base/Axis.h>
@ -152,6 +153,10 @@ App::DocumentObjectExecReturn *Groove::execute(void)
support.Move(invObjLoc); support.Move(invObjLoc);
sketchshape.Move(invObjLoc); sketchshape.Move(invObjLoc);
// Check distance between sketchshape and axis - to avoid failures and crashes
if (checkLineCrossesFace(gp_Lin(pnt, dir), TopoDS::Face(sketchshape)))
return new App::DocumentObjectExecReturn("Revolve axis intersects the sketch");
// revolve the face to a solid // revolve the face to a solid
BRepPrimAPI_MakeRevol RevolMaker(sketchshape, gp_Ax1(pnt, dir), angle); BRepPrimAPI_MakeRevol RevolMaker(sketchshape, gp_Ax1(pnt, dir), angle);

View File

@ -33,6 +33,7 @@
# include <TopExp_Explorer.hxx> # include <TopExp_Explorer.hxx>
# include <BRepAlgoAPI_Fuse.hxx> # include <BRepAlgoAPI_Fuse.hxx>
# include <Precision.hxx> # include <Precision.hxx>
# include <gp_Lin.hxx>
#endif #endif
#include <Base/Axis.h> #include <Base/Axis.h>
@ -40,6 +41,7 @@
#include <Base/Tools.h> #include <Base/Tools.h>
#include "FeatureRevolution.h" #include "FeatureRevolution.h"
#include <Base/Console.h>
using namespace PartDesign; using namespace PartDesign;
@ -158,6 +160,10 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
support.Move(invObjLoc); support.Move(invObjLoc);
sketchshape.Move(invObjLoc); sketchshape.Move(invObjLoc);
// Check distance between sketchshape and axis - to avoid failures and crashes
if (checkLineCrossesFace(gp_Lin(pnt, dir), TopoDS::Face(sketchshape)))
return new App::DocumentObjectExecReturn("Revolve axis intersects the sketch");
// revolve the face to a solid // revolve the face to a solid
BRepPrimAPI_MakeRevol RevolMaker(sketchshape, gp_Ax1(pnt, dir), angle); BRepPrimAPI_MakeRevol RevolMaker(sketchshape, gp_Ax1(pnt, dir), angle);

View File

@ -52,6 +52,11 @@
# include <ShapeAnalysis_Surface.hxx> # include <ShapeAnalysis_Surface.hxx>
# include <ShapeFix_Shape.hxx> # include <ShapeFix_Shape.hxx>
# include <Standard_Version.hxx> # include <Standard_Version.hxx>
# include <BRepBuilderAPI_MakeEdge.hxx>
# include <Extrema_ExtCC.hxx>
# include <Extrema_POnCurv.hxx>
# include <BRepAdaptor_CompCurve.hxx>
# include <BRepAdaptor_Curve.hxx>
#endif #endif
@ -532,6 +537,61 @@ const bool SketchBased::checkWireInsideFace(const TopoDS_Wire& wire, const TopoD
return (proj.More() && proj.Current().Closed()); return (proj.More() && proj.Current().Closed());
} }
const bool SketchBased::checkLineCrossesFace(const gp_Lin &line, const TopoDS_Face &face) {
// 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
// axis in two or more points
// Note: And it only works on closed outer wires
TopoDS_Wire outerWire = ShapeAnalysis::OuterWire(face);
BRepBuilderAPI_MakeEdge mkEdge(line);
if (!mkEdge.IsDone())
throw Base::Exception("Revolve: Unexpected OCE failure");
BRepAdaptor_Curve axis(TopoDS::Edge(mkEdge.Shape()));
TopExp_Explorer ex;
int intersections = 0;
std::vector<gp_Pnt> intersectionpoints;
// Note: We need to look at evey edge separately to catch coincident lines
for (ex.Init(outerWire, TopAbs_EDGE); ex.More(); ex.Next()) {
BRepAdaptor_Curve edge(TopoDS::Edge(ex.Current()));
Extrema_ExtCC intersector(axis, edge);
if (intersector.IsDone()) {
for (int i = 1; i <= intersector.NbExt(); i++) {
if (intersector.SquareDistance(i) < Precision::Confusion()) {
if (intersector.IsParallel()) {
// A line that is coincident with the axis produces three intersections
// 1 with the line itself and 2 with the adjacent edges
intersections -= 2;
} else {
Extrema_POnCurv p1, p2;
intersector.Points(i, p1, p2);
intersectionpoints.push_back(p1.Value());
intersections++;
}
}
}
}
}
// Note: We might check this inside the loop but then we have to rely on TopExp_Explorer
// returning the wire's edges in adjacent order (because of the coincident line checking)
if (intersections > 1) {
// Check that we don't touch the sketchface just in two identical vertices
if ((intersectionpoints.size() == 2) &&
(intersectionpoints[0].IsEqual(intersectionpoints[1], Precision::Confusion())))
return false;
else
return true;
}
return false;
}
void SketchBased::remapSupportShape(const TopoDS_Shape& newShape) void SketchBased::remapSupportShape(const TopoDS_Shape& newShape)
{ {
TopTools_IndexedMapOfShape faceMap; TopTools_IndexedMapOfShape faceMap;

View File

@ -32,6 +32,7 @@ class TopoDS_Shape;
class TopoDS_Face; class TopoDS_Face;
class TopoDS_Wire; class TopoDS_Wire;
class gp_Dir; class gp_Dir;
class gp_Lin;
namespace PartDesign namespace PartDesign
{ {
@ -110,6 +111,10 @@ protected:
static const bool checkWireInsideFace(const TopoDS_Wire& wire, static const bool checkWireInsideFace(const TopoDS_Wire& wire,
const TopoDS_Face& face, const TopoDS_Face& face,
const gp_Dir& dir); const gp_Dir& dir);
/// Check whether the line crosses the face (line and face must be on the same plane)
static const bool checkLineCrossesFace(const gp_Lin& line, const TopoDS_Face& face);
}; };
} //namespace PartDesign } //namespace PartDesign