issue #0003921: Crash when opening document with datum point intersecting line and plane
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
//====================================================================
|
||||
|
||||
Reference in New Issue
Block a user