0052477: Incorrect work of solid construction algorithm on not valid input data

This commit is contained in:
skv 2014-08-21 15:48:54 +04:00
parent 5c9b06b29d
commit 9b95aa0085

View File

@ -44,6 +44,7 @@
#include <BRepBuilderAPI_Sewing.hxx> #include <BRepBuilderAPI_Sewing.hxx>
#include <BRepBuilderAPI_MakeWire.hxx> #include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx> #include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeSolid.hxx>
#include <BRepCheck.hxx> #include <BRepCheck.hxx>
#include <BRepCheck_Analyzer.hxx> #include <BRepCheck_Analyzer.hxx>
#include <BRepCheck_Shell.hxx> #include <BRepCheck_Shell.hxx>
@ -133,10 +134,13 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
TopoDS_Shape aShape; TopoDS_Shape aShape;
TCollection_AsciiString aWarning; TCollection_AsciiString aWarning;
TopAbs_ShapeEnum anExpectedType = TopAbs_SHAPE;
BRep_Builder B; BRep_Builder B;
if (aType == WIRE_EDGES) { if (aType == WIRE_EDGES) {
anExpectedType = TopAbs_WIRE;
Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
Standard_Real aTolerance = aCI.GetTolerance(); Standard_Real aTolerance = aCI.GetTolerance();
@ -146,6 +150,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
aShape = MakeWireFromEdges(aShapes, aTolerance); aShape = MakeWireFromEdges(aShapes, aTolerance);
} }
else if (aType == FACE_WIRE) { else if (aType == FACE_WIRE) {
anExpectedType = TopAbs_FACE;
Handle(GEOM_Function) aRefBase = aCI.GetBase(); Handle(GEOM_Function) aRefBase = aCI.GetBase();
TopoDS_Shape aShapeBase = aRefBase->GetValue(); TopoDS_Shape aShapeBase = aRefBase->GetValue();
if (aShapeBase.IsNull()) Standard_NullObject::Raise("Argument Shape is null"); if (aShapeBase.IsNull()) Standard_NullObject::Raise("Argument Shape is null");
@ -179,6 +185,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
} }
} }
else if (aType == FACE_WIRES) { else if (aType == FACE_WIRES) {
anExpectedType = TopAbs_FACE;
// Try to build a face from a set of wires and edges // Try to build a face from a set of wires and edges
int ind; int ind;
@ -295,6 +303,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
} }
} }
else if (aType == SHELL_FACES) { else if (aType == SHELL_FACES) {
anExpectedType = TopAbs_SHELL;
Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
unsigned int ind, nbshapes = aShapes->Length(); unsigned int ind, nbshapes = aShapes->Length();
@ -352,6 +362,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
} }
else if (aType == SOLID_SHELL) { else if (aType == SOLID_SHELL) {
anExpectedType = TopAbs_SOLID;
Handle(GEOM_Function) aRefShell = aCI.GetBase(); Handle(GEOM_Function) aRefShell = aCI.GetBase();
TopoDS_Shape aShapeShell = aRefShell->GetValue(); TopoDS_Shape aShapeShell = aRefShell->GetValue();
if (!aShapeShell.IsNull() && aShapeShell.ShapeType() == TopAbs_COMPOUND) { if (!aShapeShell.IsNull() && aShapeShell.ShapeType() == TopAbs_COMPOUND) {
@ -379,11 +391,12 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
} }
else if (aType == SOLID_SHELLS) { else if (aType == SOLID_SHELLS) {
anExpectedType = TopAbs_SOLID;
Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
unsigned int ind, nbshapes = aShapes->Length(); unsigned int ind, nbshapes = aShapes->Length();
Standard_Integer ish = 0; Standard_Integer ish = 0;
TopoDS_Solid Sol; BRepBuilderAPI_MakeSolid aMkSolid;
B.MakeSolid(Sol);
// add shapes // add shapes
for (ind = 1; ind <= nbshapes; ind++) { for (ind = 1; ind <= nbshapes; ind++) {
@ -397,11 +410,13 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
if (It.More()) aShapeShell = It.Value(); if (It.More()) aShapeShell = It.Value();
} }
if (aShapeShell.ShapeType() == TopAbs_SHELL) { if (aShapeShell.ShapeType() == TopAbs_SHELL) {
B.Add(Sol, aShapeShell); aMkSolid.Add(TopoDS::Shell(aShapeShell));
ish++; ish++;
} }
} }
if (ish == 0) return 0; if (ish == 0 || !aMkSolid.IsDone()) return 0;
TopoDS_Solid Sol = aMkSolid.Solid();
BRepClass3d_SolidClassifier SC (Sol); BRepClass3d_SolidClassifier SC (Sol);
SC.PerformInfinitePoint(Precision::Confusion()); SC.PerformInfinitePoint(Precision::Confusion());
if (SC.State() == TopAbs_IN) if (SC.State() == TopAbs_IN)
@ -410,6 +425,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
aShape = Sol; aShape = Sol;
} }
else if (aType == COMPOUND_SHAPES) { else if (aType == COMPOUND_SHAPES) {
anExpectedType = TopAbs_COMPOUND;
Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
unsigned int ind, nbshapes = aShapes->Length(); unsigned int ind, nbshapes = aShapes->Length();
@ -453,6 +470,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
} }
*/ */
else if (aType == EDGE_WIRE) { else if (aType == EDGE_WIRE) {
anExpectedType = TopAbs_EDGE;
Handle(GEOM_Function) aRefBase = aCI.GetBase(); Handle(GEOM_Function) aRefBase = aCI.GetBase();
TopoDS_Shape aWire = aRefBase->GetValue(); TopoDS_Shape aWire = aRefBase->GetValue();
Standard_Real LinTol = aCI.GetTolerance(); Standard_Real LinTol = aCI.GetTolerance();
@ -462,6 +481,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
aShape = MakeEdgeFromWire(aWire, LinTol, AngTol); aShape = MakeEdgeFromWire(aWire, LinTol, AngTol);
} }
else if (aType == EDGE_CURVE_LENGTH) { else if (aType == EDGE_CURVE_LENGTH) {
anExpectedType = TopAbs_EDGE;
GEOMImpl_IVector aVI (aFunction); GEOMImpl_IVector aVI (aFunction);
// RefCurve // RefCurve
@ -536,6 +557,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
if (aME.IsDone()) if (aME.IsDone())
aShape = aME.Shape(); aShape = aME.Shape();
} else if (aType == SHAPE_ISOLINE) { } else if (aType == SHAPE_ISOLINE) {
anExpectedType = TopAbs_EDGE;
GEOMImpl_IIsoline aII (aFunction); GEOMImpl_IIsoline aII (aFunction);
Handle(GEOM_Function) aRefFace = aII.GetFace(); Handle(GEOM_Function) aRefFace = aII.GetFace();
TopoDS_Shape aShapeFace = aRefFace->GetValue(); TopoDS_Shape aShapeFace = aRefFace->GetValue();
@ -577,6 +600,33 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
aShape = aSfs->Shape(); aShape = aSfs->Shape();
} }
// Check if the result shape type is compatible with the expected.
const TopAbs_ShapeEnum aShType = aShape.ShapeType();
if (anExpectedType != TopAbs_SHAPE && anExpectedType != aShType) {
if (aShType == TopAbs_COMPOUND) {
// The result is compound. Check its sub-shapes.
TopoDS_Iterator anIter(aShape);
if (!anIter.More()) {
// The result is an empty compound.
Standard_ConstructionError::Raise("Result type check failed");
}
for (; anIter.More(); anIter.Next()) {
const TopAbs_ShapeEnum aSubType = anIter.Value().ShapeType();
if (anExpectedType != aSubType) {
// There is an incompatible type.
Standard_ConstructionError::Raise("Result type check failed");
}
}
} else {
// There is an incompatible type.
Standard_ConstructionError::Raise("Result type check failed");
}
}
aFunction->SetValue(aShape); aFunction->SetValue(aShape);
log.SetTouched(Label()); log.SetTouched(Label());