Added check to Revolution and Groove for sketch axis intersecting the sketch face
This commit is contained in:
parent
8a1c9f0651
commit
8371982dfc
|
@ -33,6 +33,7 @@
|
|||
# include <TopExp_Explorer.hxx>
|
||||
# include <BRepAlgoAPI_Cut.hxx>
|
||||
# include <Precision.hxx>
|
||||
# include <gp_Lin.hxx>
|
||||
#endif
|
||||
|
||||
#include <Base/Axis.h>
|
||||
|
@ -76,12 +77,12 @@ App::DocumentObjectExecReturn *Groove::execute(void)
|
|||
return new App::DocumentObjectExecReturn("Angle of groove too small");
|
||||
if (angle > 360.0)
|
||||
return new App::DocumentObjectExecReturn("Angle of groove too large");
|
||||
|
||||
|
||||
angle = Base::toRadians<double>(angle);
|
||||
// Reverse angle if selected
|
||||
if (Reversed.getValue() && !Midplane.getValue())
|
||||
angle *= (-1.0);
|
||||
|
||||
|
||||
Part::Part2DObject* sketch = 0;
|
||||
std::vector<TopoDS_Wire> wires;
|
||||
TopoDS_Shape support;
|
||||
|
@ -152,6 +153,10 @@ App::DocumentObjectExecReturn *Groove::execute(void)
|
|||
support.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
|
||||
BRepPrimAPI_MakeRevol RevolMaker(sketchshape, gp_Ax1(pnt, dir), angle);
|
||||
|
||||
|
@ -159,7 +164,7 @@ App::DocumentObjectExecReturn *Groove::execute(void)
|
|||
TopoDS_Shape result = RevolMaker.Shape();
|
||||
// set the subtractive shape property for later usage in e.g. pattern
|
||||
this->SubShape.setValue(result);
|
||||
|
||||
|
||||
// cut out groove to get one result object
|
||||
BRepAlgoAPI_Cut mkCut(support, result);
|
||||
// Let's check if the fusion has been successful
|
||||
|
@ -181,7 +186,7 @@ App::DocumentObjectExecReturn *Groove::execute(void)
|
|||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
if (std::string(e->GetMessageString()) == "TopoDS::Face")
|
||||
return new App::DocumentObjectExecReturn("Could not create face from sketch.\n"
|
||||
return new App::DocumentObjectExecReturn("Could not create face from sketch.\n"
|
||||
"Intersecting sketch entities or multiple faces in a sketch are not allowed.");
|
||||
else
|
||||
return new App::DocumentObjectExecReturn(e->GetMessageString());
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
# include <TopExp_Explorer.hxx>
|
||||
# include <BRepAlgoAPI_Fuse.hxx>
|
||||
# include <Precision.hxx>
|
||||
# include <gp_Lin.hxx>
|
||||
#endif
|
||||
|
||||
#include <Base/Axis.h>
|
||||
|
@ -40,6 +41,7 @@
|
|||
#include <Base/Tools.h>
|
||||
|
||||
#include "FeatureRevolution.h"
|
||||
#include <Base/Console.h>
|
||||
|
||||
|
||||
using namespace PartDesign;
|
||||
|
@ -76,12 +78,12 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
|
|||
return new App::DocumentObjectExecReturn("Angle of groove too small");
|
||||
if (angle > 360.0)
|
||||
return new App::DocumentObjectExecReturn("Angle of groove too large");
|
||||
|
||||
|
||||
angle = Base::toRadians<double>(angle);
|
||||
// Reverse angle if selected
|
||||
if (Reversed.getValue() && !Midplane.getValue())
|
||||
angle *= (-1.0);
|
||||
|
||||
|
||||
Part::Part2DObject* sketch = 0;
|
||||
std::vector<TopoDS_Wire> wires;
|
||||
try {
|
||||
|
@ -90,7 +92,7 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
|
|||
} catch (const Base::Exception& e) {
|
||||
return new App::DocumentObjectExecReturn(e.what());
|
||||
}
|
||||
|
||||
|
||||
TopoDS_Shape support;
|
||||
try {
|
||||
support = getSupportShape();
|
||||
|
@ -158,6 +160,10 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
|
|||
support.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
|
||||
BRepPrimAPI_MakeRevol RevolMaker(sketchshape, gp_Ax1(pnt, dir), angle);
|
||||
|
||||
|
@ -186,7 +192,7 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
|
|||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
if (std::string(e->GetMessageString()) == "TopoDS::Face")
|
||||
return new App::DocumentObjectExecReturn("Could not create face from sketch.\n"
|
||||
return new App::DocumentObjectExecReturn("Could not create face from sketch.\n"
|
||||
"Intersecting sketch entities or multiple faces in a sketch are not allowed.");
|
||||
else
|
||||
return new App::DocumentObjectExecReturn(e->GetMessageString());
|
||||
|
|
|
@ -52,6 +52,11 @@
|
|||
# include <ShapeAnalysis_Surface.hxx>
|
||||
# include <ShapeFix_Shape.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
|
||||
|
||||
|
||||
|
@ -532,6 +537,61 @@ 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) {
|
||||
// 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)
|
||||
{
|
||||
TopTools_IndexedMapOfShape faceMap;
|
||||
|
|
|
@ -32,6 +32,7 @@ class TopoDS_Shape;
|
|||
class TopoDS_Face;
|
||||
class TopoDS_Wire;
|
||||
class gp_Dir;
|
||||
class gp_Lin;
|
||||
|
||||
namespace PartDesign
|
||||
{
|
||||
|
@ -102,7 +103,7 @@ protected:
|
|||
const std::string& method,
|
||||
const gp_Dir& direction,
|
||||
const double L,
|
||||
const double L2,
|
||||
const double L2,
|
||||
const bool midplane,
|
||||
const bool reversed);
|
||||
|
||||
|
@ -110,6 +111,10 @@ protected:
|
|||
static const bool checkWireInsideFace(const TopoDS_Wire& wire,
|
||||
const TopoDS_Face& face,
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue
Block a user