Re-worked Part::checkIntersection to give less false positives for pattern features
This commit is contained in:
parent
5df7f2db88
commit
18da371546
|
@ -27,6 +27,7 @@
|
||||||
# include <gp_Trsf.hxx>
|
# include <gp_Trsf.hxx>
|
||||||
# include <gp_Ax1.hxx>
|
# include <gp_Ax1.hxx>
|
||||||
# include <BRepBuilderAPI_MakeShape.hxx>
|
# include <BRepBuilderAPI_MakeShape.hxx>
|
||||||
|
# include <BRepAlgoAPI_Fuse.hxx>
|
||||||
# include <BRepAlgoAPI_Common.hxx>
|
# include <BRepAlgoAPI_Common.hxx>
|
||||||
# include <TopTools_ListIteratorOfListOfShape.hxx>
|
# include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||||
# include <TopExp.hxx>
|
# include <TopExp.hxx>
|
||||||
|
@ -336,33 +337,50 @@ std::vector<Part::cutFaces> Part::findAllFacesCutBy(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool Part::checkIntersection(const TopoDS_Shape& first, const TopoDS_Shape& second, const bool quick) {
|
const bool Part::checkIntersection(const TopoDS_Shape& first, const TopoDS_Shape& second,
|
||||||
|
const bool quick, const bool touch_is_intersection) {
|
||||||
Bnd_Box first_bb, second_bb;
|
Bnd_Box first_bb, second_bb;
|
||||||
BRepBndLib::Add(first, first_bb);
|
BRepBndLib::Add(first, first_bb);
|
||||||
first_bb.SetGap(0);
|
first_bb.SetGap(0);
|
||||||
BRepBndLib::Add(second, second_bb);
|
BRepBndLib::Add(second, second_bb);
|
||||||
second_bb.SetGap(0);
|
second_bb.SetGap(0);
|
||||||
|
|
||||||
// Note: Both tests fail if the objects are touching one another at zero distance!
|
// Note: This test fails if the objects are touching one another at zero distance
|
||||||
if (first_bb.IsOut(second_bb))
|
if (first_bb.IsOut(second_bb))
|
||||||
return false; // no intersection
|
return false; // no intersection
|
||||||
//if (first_bb.Distance(second_bb) > Precision::Confusion())
|
|
||||||
// return false;
|
|
||||||
if (quick)
|
if (quick)
|
||||||
return true; // assumed intersection
|
return true; // assumed intersection
|
||||||
|
|
||||||
// Try harder
|
// Try harder
|
||||||
BRepAlgoAPI_Common mkCommon(first, second);
|
if (touch_is_intersection) {
|
||||||
// FIXME: Error in boolean operation, return true by default
|
// If both shapes fuse to a single solid, then they intersect
|
||||||
if (!mkCommon.IsDone())
|
BRepAlgoAPI_Fuse mkFuse(first, second);
|
||||||
return true;
|
if (!mkFuse.IsDone())
|
||||||
if (mkCommon.Shape().IsNull())
|
return false;
|
||||||
return true;
|
if (mkFuse.Shape().IsNull())
|
||||||
|
return false;
|
||||||
|
|
||||||
TopExp_Explorer xp;
|
// Did we get one or two solids?
|
||||||
xp.Init(mkCommon.Shape(),TopAbs_SOLID);
|
TopExp_Explorer xp;
|
||||||
if (xp.More())
|
xp.Init(mkFuse.Shape(),TopAbs_SOLID);
|
||||||
return true;
|
if (xp.More()) {
|
||||||
|
// At least one solid
|
||||||
|
xp.Next();
|
||||||
|
return (xp.More() == Standard_False);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If both shapes have common material, then they intersect
|
||||||
|
BRepAlgoAPI_Common mkCommon(first, second);
|
||||||
|
if (!mkCommon.IsDone())
|
||||||
|
return false;
|
||||||
|
if (mkCommon.Shape().IsNull())
|
||||||
|
return false;
|
||||||
|
|
||||||
return false;
|
// Did we get a solid?
|
||||||
|
TopExp_Explorer xp;
|
||||||
|
xp.Init(mkCommon.Shape(),TopAbs_SOLID);
|
||||||
|
return (xp.More() == Standard_True);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,9 +141,17 @@ std::vector<cutFaces> findAllFacesCutBy(const TopoDS_Shape& shape,
|
||||||
* 1. Bounding box check only - quick but inaccurate
|
* 1. Bounding box check only - quick but inaccurate
|
||||||
* 2. Bounding box check plus (if necessary) boolean operation - costly but accurate
|
* 2. Bounding box check plus (if necessary) boolean operation - costly but accurate
|
||||||
* Return true if the shapes intersect, false if they don't
|
* Return true if the shapes intersect, false if they don't
|
||||||
|
* The flag touch_is_intersection decides whether shapes touching at distance zero are regarded
|
||||||
|
* as intersecting or not
|
||||||
|
* 1. If set to true, a true check result means that a boolean fuse operation between the two shapes
|
||||||
|
* will return a single solid
|
||||||
|
* 2. If set to false, a true check result means that a boolean common operation will return a
|
||||||
|
* valid solid
|
||||||
|
* If there is any error in the boolean operations, the check always returns false
|
||||||
*/
|
*/
|
||||||
PartExport
|
PartExport
|
||||||
const bool checkIntersection(const TopoDS_Shape& first, const TopoDS_Shape& second, const bool quick = true);
|
const bool checkIntersection(const TopoDS_Shape& first, const TopoDS_Shape& second,
|
||||||
|
const bool quick, const bool touch_is_intersection);
|
||||||
|
|
||||||
} //namespace Part
|
} //namespace Part
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
|
||||||
return new App::DocumentObjectExecReturn("Transformation failed", (*o));
|
return new App::DocumentObjectExecReturn("Transformation failed", (*o));
|
||||||
|
|
||||||
// Check for intersection with support
|
// Check for intersection with support
|
||||||
if (!Part::checkIntersection(support, mkTrf.Shape(), false)) {
|
if (!Part::checkIntersection(support, mkTrf.Shape(), false, true)) {
|
||||||
Base::Console().Warning("Transformed shape does not intersect support %s: Removed\n", (*o)->getNameInDocument());
|
Base::Console().Warning("Transformed shape does not intersect support %s: Removed\n", (*o)->getNameInDocument());
|
||||||
// Note: The removal happens in getSolid() after the fuse
|
// Note: The removal happens in getSolid() after the fuse
|
||||||
rejected.push_back(*t);
|
rejected.push_back(*t);
|
||||||
|
@ -203,7 +203,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
|
||||||
if (v_transformedShapes.size() == 1)
|
if (v_transformedShapes.size() == 1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (Part::checkIntersection(shape, *s, false))
|
if (Part::checkIntersection(shape, *s, false, false))
|
||||||
return new App::DocumentObjectExecReturn("Transformed objects are overlapping, try using a higher length or reducing the number of occurrences", (*o));
|
return new App::DocumentObjectExecReturn("Transformed objects are overlapping, try using a higher length or reducing the number of occurrences", (*o));
|
||||||
// Note: This limitation could be overcome by fusing the transformed features instead of
|
// Note: This limitation could be overcome by fusing the transformed features instead of
|
||||||
// compounding them, probably at the expense of quite a bit of performance and complexity
|
// compounding them, probably at the expense of quite a bit of performance and complexity
|
||||||
|
@ -218,7 +218,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
|
||||||
std::vector<TopoDS_Shape>::const_iterator s2 = s;
|
std::vector<TopoDS_Shape>::const_iterator s2 = s;
|
||||||
s2++;
|
s2++;
|
||||||
for (; s2 != v_transformedShapes.end(); s2++)
|
for (; s2 != v_transformedShapes.end(); s2++)
|
||||||
if (Part::checkIntersection(*s, *s2, false))
|
if (Part::checkIntersection(*s, *s2, false, false))
|
||||||
return new App::DocumentObjectExecReturn("Transformed objects are overlapping, try using a higher length or reducing the number of occurrences", (*o));
|
return new App::DocumentObjectExecReturn("Transformed objects are overlapping, try using a higher length or reducing the number of occurrences", (*o));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user