fixes 0003333: Wrong behaviour of fuse operation

This commit is contained in:
wmayer
2018-09-25 17:53:37 +02:00
parent 510eed1caf
commit 6c87152d36
2 changed files with 75 additions and 6 deletions

View File

@@ -1486,7 +1486,7 @@ TopoDS_Shape TopoShape::cut(TopoDS_Shape shape) const
if (shape.IsNull())
Standard_Failure::Raise("Tool shape is null");
BRepAlgoAPI_Cut mkCut(this->_Shape, shape);
return mkCut.Shape();
return makeShell(mkCut.Shape());
}
TopoDS_Shape TopoShape::cut(const std::vector<TopoDS_Shape>& shapes, Standard_Real tolerance) const
@@ -1521,7 +1521,7 @@ TopoDS_Shape TopoShape::cut(const std::vector<TopoDS_Shape>& shapes, Standard_Re
throw Base::RuntimeError("Multi cut failed");
TopoDS_Shape resShape = mkCut.Shape();
return resShape;
return makeShell(resShape);
#endif
}
@@ -1532,7 +1532,7 @@ TopoDS_Shape TopoShape::common(TopoDS_Shape shape) const
if (shape.IsNull())
Standard_Failure::Raise("Tool shape is null");
BRepAlgoAPI_Common mkCommon(this->_Shape, shape);
return mkCommon.Shape();
return makeShell(mkCommon.Shape());
}
TopoDS_Shape TopoShape::common(const std::vector<TopoDS_Shape>& shapes, Standard_Real tolerance) const
@@ -1567,7 +1567,7 @@ TopoDS_Shape TopoShape::common(const std::vector<TopoDS_Shape>& shapes, Standard
throw Base::RuntimeError("Multi common failed");
TopoDS_Shape resShape = mkCommon.Shape();
return resShape;
return makeShell(resShape);
#endif
}
@@ -1578,7 +1578,7 @@ TopoDS_Shape TopoShape::fuse(TopoDS_Shape shape) const
if (shape.IsNull())
Standard_Failure::Raise("Tool shape is null");
BRepAlgoAPI_Fuse mkFuse(this->_Shape, shape);
return mkFuse.Shape();
return makeShell(mkFuse.Shape());
}
TopoDS_Shape TopoShape::fuse(const std::vector<TopoDS_Shape>& shapes, Standard_Real tolerance) const
@@ -1627,7 +1627,7 @@ TopoDS_Shape TopoShape::fuse(const std::vector<TopoDS_Shape>& shapes, Standard_R
TopoDS_Shape resShape = mkFuse.Shape();
#endif
return resShape;
return makeShell(resShape);
}
TopoDS_Shape TopoShape::oldFuse(TopoDS_Shape shape) const
@@ -3449,3 +3449,71 @@ TopoDS_Shape TopoShape::defeaturing(const std::vector<TopoDS_Shape>& s) const
return defeat.Shape();
#endif
}
/**
* @brief TopoShape::makeShell
* If the input shape is a compound with faces not being part of a shell
* it tries to make a shell.
* If this operation fails or if the input shape is not a compound or a compound
* with not only faces the input shape is returned.
* @return Shell or passed shape
*/
TopoDS_Shape TopoShape::makeShell(const TopoDS_Shape& input) const
{
if (input.IsNull())
return input;
if (input.ShapeType() != TopAbs_COMPOUND)
return input;
// we need a compound that consists of only faces
TopExp_Explorer it;
// no shells
it.Init(input, TopAbs_SHELL);
if (it.More())
return input;
// no wires outside a face
it.Init(input, TopAbs_WIRE, TopAbs_FACE);
if (it.More())
return input;
// no edges outside a wire
it.Init(input, TopAbs_EDGE, TopAbs_WIRE);
if (it.More())
return input;
// no vertexes outside an edge
it.Init(input, TopAbs_VERTEX, TopAbs_EDGE);
if (it.More())
return input;
BRep_Builder builder;
TopoDS_Shape shape;
TopoDS_Shell shell;
builder.MakeShell(shell);
try {
for (it.Init(input, TopAbs_FACE); it.More(); it.Next()) {
if (!it.Current().IsNull())
builder.Add(shell, it.Current());
}
shape = shell;
BRepCheck_Analyzer check(shell);
if (!check.IsValid()) {
ShapeUpgrade_ShellSewing sewShell;
shape = sewShell.ApplySewing(shell);
}
if (shape.IsNull())
return input;
if (shape.ShapeType() != TopAbs_SHELL)
return input;
return shape; // success
}
catch (Standard_Failure&) {
return input;
}
}

View File

@@ -238,6 +238,7 @@ public:
bool removeInternalWires(double);
TopoDS_Shape removeSplitter() const;
TopoDS_Shape defeaturing(const std::vector<TopoDS_Shape>& s) const;
TopoDS_Shape makeShell(const TopoDS_Shape&) const;
//@}
/** @name Getting basic geometric entities */