issue #0003921: Crash when opening document with datum point intersecting line and plane

This commit is contained in:
wmayer
2019-06-16 19:31:06 +02:00
parent 032485f7ca
commit 5a326e4b50
2 changed files with 64 additions and 11 deletions

View File

@@ -48,6 +48,7 @@
# include <BRepBuilderAPI_MakeFace.hxx>
# include <BRepBuilderAPI_MakeEdge.hxx>
# include <BRepExtrema_DistShapeShape.hxx>
# include <BRepIntCurveSurface_Inter.hxx>
# include <TopTools_HSequenceOfShape.hxx>
# include <ShapeExtend_Explorer.hxx>
# include <GProp_GProps.hxx>
@@ -2061,17 +2062,8 @@ Base::Placement AttachEnginePoint::calculateAttachedPlacement(Base::Placement or
throw Base::ValueError("Null shape in AttachEnginePoint::calculateAttachedPlacement()!");
if (shapes[1]->IsNull())
throw Base::ValueError("Null shape in AttachEnginePoint::calculateAttachedPlacement()!");
BRepExtrema_DistShapeShape distancer (*(shapes[0]), *(shapes[1]));
if (!distancer.IsDone())
throw Base::ValueError("AttachEnginePoint::calculateAttachedPlacement: proximity calculation failed.");
if (distancer.NbSolution()>1)
Base::Console().Warning("AttachEnginePoint::calculateAttachedPlacement: proximity calculation gave %i solutions, ambiguous.\n",int(distancer.NbSolution()));
gp_Pnt p1 = distancer.PointOnShape1(1);
gp_Pnt p2 = distancer.PointOnShape2(1);
if (mmode == mm0ProximityPoint1)
BasePoint = p1;
else
BasePoint = p2;
BasePoint = getProximityPoint(mmode, *(shapes[0]), *(shapes[1]));
}break;
case mm0CenterOfMass:{
GProp_GProps gpr = AttachEngine::getInertialPropsOfShape(shapes);
@@ -2093,3 +2085,61 @@ Base::Placement AttachEnginePoint::calculateAttachedPlacement(Base::Placement or
return plm;
}
gp_Pnt AttachEnginePoint::getProximityPoint(eMapMode mmode, const TopoDS_Shape& s1, const TopoDS_Shape& s2) const
{
// #0003921: Crash when opening document with datum point intersecting line and plane
//
// BRepExtrema_DistanceSS is used inside BRepExtrema_DistShapeShape and can cause
// a crash if the input shape is an unlimited face.
// So, when the input is a face and an edge then before checking for minimum distances
// try to determine intersection points.
try {
TopoDS_Shape face, edge;
if (s1.ShapeType() == TopAbs_FACE &&
s2.ShapeType() == TopAbs_EDGE) {
face = s1;
edge = s2;
}
else if (s1.ShapeType() == TopAbs_EDGE &&
s2.ShapeType() == TopAbs_FACE) {
edge = s1;
face = s2;
}
// edge and face
if (!edge.IsNull() && !face.IsNull()) {
BRepAdaptor_Curve crv(TopoDS::Edge(edge));
BRepIntCurveSurface_Inter intCS;
intCS.Init(face, crv.Curve(), Precision::Confusion());
std::vector<gp_Pnt> points;
for (; intCS.More(); intCS.Next()) {
gp_Pnt pnt = intCS.Pnt();
points.push_back(pnt);
}
if (points.size() > 1)
Base::Console().Warning("AttachEnginePoint::calculateAttachedPlacement: proximity calculation gave %d solutions, ambiguous.\n", int(points.size()));
// if an intersection is found return the first hit
// otherwise continue with BRepExtrema_DistShapeShape
if (!points.empty())
return points.front();
}
}
catch (Standard_Failure) {
// ignore
}
BRepExtrema_DistShapeShape distancer (s1, s2);
if (!distancer.IsDone())
throw Base::ValueError("AttachEnginePoint::calculateAttachedPlacement: proximity calculation failed.");
if (distancer.NbSolution() > 1)
Base::Console().Warning("AttachEnginePoint::calculateAttachedPlacement: proximity calculation gave %i solutions, ambiguous.\n",int(distancer.NbSolution()));
gp_Pnt p1 = distancer.PointOnShape1(1);
gp_Pnt p2 = distancer.PointOnShape2(1);
if (mmode == mm0ProximityPoint1)
return p1;
else
return p2;
}

View File

@@ -456,6 +456,9 @@ public:
AttachEnginePoint();
virtual AttachEnginePoint* copy() const;
virtual Base::Placement calculateAttachedPlacement(Base::Placement origPlacement) const;
private:
gp_Pnt getProximityPoint(eMapMode mode, const TopoDS_Shape& s1, const TopoDS_Shape& s2) const;
};
//====================================================================