Fix transformation support, so that support is updated with any previous transformation executed
This commit is contained in:
@@ -40,9 +40,6 @@
|
||||
# include <Bnd_Box.hxx>
|
||||
# include <BRepBndLib.hxx>
|
||||
# include <BRepExtrema_DistShapeShape.hxx>
|
||||
# include <BRep_Tool.hxx>
|
||||
# include <TopoDS_Vertex.hxx>
|
||||
# include <TopoDS.hxx>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -341,7 +338,6 @@ std::vector<Part::cutFaces> Part::findAllFacesCutBy(
|
||||
bool Part::checkIntersection(const TopoDS_Shape& first, const TopoDS_Shape& second,
|
||||
const bool quick, const bool touch_is_intersection) {
|
||||
|
||||
//return true;
|
||||
Bnd_Box first_bb, second_bb;
|
||||
BRepBndLib::Add(first, first_bb);
|
||||
first_bb.SetGap(0);
|
||||
@@ -349,15 +345,19 @@ bool Part::checkIntersection(const TopoDS_Shape& first, const TopoDS_Shape& seco
|
||||
second_bb.SetGap(0);
|
||||
|
||||
// Note: This test fails if the objects are touching one another at zero distance
|
||||
// if it fails sometimes when touching and touching is intersection, then please check further
|
||||
// unless the user asked for quick
|
||||
|
||||
// Improving reliability: If it fails sometimes when touching and touching is intersection,
|
||||
// then please check further unless the user asked for a quick potentially unreliable result
|
||||
if (first_bb.IsOut(second_bb) && !touch_is_intersection)
|
||||
return false; // no intersection
|
||||
if (quick && first_bb.IsOut(second_bb))
|
||||
if (quick && !first_bb.IsOut(second_bb))
|
||||
return true; // assumed intersection
|
||||
|
||||
// Try harder
|
||||
|
||||
// This has been disabled because of:
|
||||
// https://www.freecadweb.org/tracker/view.php?id=3065
|
||||
|
||||
//extrema method
|
||||
/*BRepExtrema_DistShapeShape extrema(first, second);
|
||||
if (!extrema.IsDone())
|
||||
@@ -374,17 +374,9 @@ bool Part::checkIntersection(const TopoDS_Shape& first, const TopoDS_Shape& seco
|
||||
//non manifold condition. 1 has to be a face
|
||||
for (int index = 1; index < extrema.NbSolution() + 1; ++index)
|
||||
{
|
||||
return true;
|
||||
gp_Pnt pnt1, pnt2;
|
||||
if (extrema.SupportTypeShape1(index) == BRepExtrema_IsVertex)
|
||||
pnt1 = BRep_Tool::Pnt(TopoDS::Vertex(extrema.SupportOnShape1(index)));
|
||||
if (extrema.SupportTypeShape2(index) == BRepExtrema_IsVertex)
|
||||
pnt2 = BRep_Tool::Pnt(TopoDS::Vertex(extrema.SupportOnShape2(index)));
|
||||
|
||||
if (extrema.SupportTypeShape1(index) == BRepExtrema_IsInFace || extrema.SupportTypeShape2(index) == BRepExtrema_IsInFace)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -256,9 +256,9 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
|
||||
}
|
||||
|
||||
// Transform the add/subshape and collect the resulting shapes for overlap testing
|
||||
typedef std::vector<std::vector<gp_Trsf>::const_iterator> trsf_it_vec;
|
||||
/*typedef std::vector<std::vector<gp_Trsf>::const_iterator> trsf_it_vec;
|
||||
trsf_it_vec v_transformations;
|
||||
std::vector<TopoDS_Shape> v_transformedShapes;
|
||||
std::vector<TopoDS_Shape> v_transformedShapes;*/
|
||||
|
||||
std::vector<gp_Trsf>::const_iterator t = transformations.begin();
|
||||
++t; // Skip first transformation, which is always the identity transformation
|
||||
@@ -276,15 +276,75 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
|
||||
|
||||
// Check for intersection with support
|
||||
try {
|
||||
|
||||
if (!Part::checkIntersection(support, mkTrf.Shape(), false, true)) {
|
||||
#ifdef FC_DEBUG // do not write this in release mode because a message appears already in the task view
|
||||
Base::Console().Warning("Transformed shape does not intersect support %s: Removed\n", (*o)->getNameInDocument());
|
||||
#endif
|
||||
nointersect_trsfms[*o].insert(t);
|
||||
} else {
|
||||
v_transformations.push_back(t);
|
||||
v_transformedShapes.push_back(mkTrf.Shape());
|
||||
// We cannot wait to fuse a transformation with the support until all the transformations are done,
|
||||
// because the "support" potentially changes with every transformation, basically when checking intersection
|
||||
// above you need:
|
||||
// 1. The original support
|
||||
// 2. Any extra support gained by any previous transformation of any previous feature (multi-feature transform)
|
||||
// 3. Any extra support gained by any previous tranformation of this feature (feature multi-trasform)
|
||||
//
|
||||
// Therefore, if the transformation succeeded, then we fuse it with the support now, before checking the intersection
|
||||
// of the next transformation.
|
||||
|
||||
/*v_transformations.push_back(t);
|
||||
v_transformedShapes.push_back(mkTrf.Shape());*/
|
||||
|
||||
// Note: Transformations that do not intersect the support are ignored in the overlap tests
|
||||
|
||||
//insert scheme here.
|
||||
/*TopoDS_Compound compoundTool;
|
||||
std::vector<TopoDS_Shape> individualTools;
|
||||
divideTools(v_transformedShapes, individualTools, compoundTool);*/
|
||||
|
||||
// Fuse/Cut the compounded transformed shapes with the support
|
||||
//TopoDS_Shape result;
|
||||
TopoDS_Shape current = support;
|
||||
|
||||
if (fuse) {
|
||||
BRepAlgoAPI_Fuse mkFuse(current, mkTrf.Shape());
|
||||
if (!mkFuse.IsDone())
|
||||
return new App::DocumentObjectExecReturn("Fusion with support failed", *o);
|
||||
// we have to get the solids (fuse sometimes creates compounds)
|
||||
current = this->getSolid(mkFuse.Shape());
|
||||
// lets check if the result is a solid
|
||||
if (current.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Resulting shape is not a solid", *o);
|
||||
/*std::vector<TopoDS_Shape>::const_iterator individualIt;
|
||||
for (individualIt = individualTools.begin(); individualIt != individualTools.end(); ++individualIt)
|
||||
{
|
||||
BRepAlgoAPI_Fuse mkFuse2(current, *individualIt);
|
||||
if (!mkFuse2.IsDone())
|
||||
return new App::DocumentObjectExecReturn("Fusion with support failed", *o);
|
||||
// we have to get the solids (fuse sometimes creates compounds)
|
||||
current = this->getSolid(mkFuse2.Shape());
|
||||
// lets check if the result is a solid
|
||||
if (current.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Resulting shape is not a solid", *o);
|
||||
}*/
|
||||
} else {
|
||||
BRepAlgoAPI_Cut mkCut(current, mkTrf.Shape());
|
||||
if (!mkCut.IsDone())
|
||||
return new App::DocumentObjectExecReturn("Cut out of support failed", *o);
|
||||
current = mkCut.Shape();
|
||||
/*std::vector<TopoDS_Shape>::const_iterator individualIt;
|
||||
for (individualIt = individualTools.begin(); individualIt != individualTools.end(); ++individualIt)
|
||||
{
|
||||
BRepAlgoAPI_Cut mkCut2(current, *individualIt);
|
||||
if (!mkCut2.IsDone())
|
||||
return new App::DocumentObjectExecReturn("Cut out of support failed", *o);
|
||||
current = this->getSolid(mkCut2.Shape());
|
||||
if (current.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Resulting shape is not a solid", *o);
|
||||
}*/
|
||||
}
|
||||
support = current; // Use result of this operation for fuse/cut of next original
|
||||
}
|
||||
} catch (Standard_Failure) {
|
||||
// Note: Ignoring this failure is probably pointless because if the intersection check fails, the later
|
||||
@@ -296,61 +356,6 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
|
||||
return new App::DocumentObjectExecReturn(msg.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (v_transformedShapes.empty())
|
||||
continue; // Skip the overlap check and go on to next original
|
||||
|
||||
if (v_transformedShapes.empty())
|
||||
continue; // Skip the boolean operation and go on to next original
|
||||
|
||||
|
||||
//insert scheme here.
|
||||
TopoDS_Compound compoundTool;
|
||||
std::vector<TopoDS_Shape> individualTools;
|
||||
divideTools(v_transformedShapes, individualTools, compoundTool);
|
||||
|
||||
// Fuse/Cut the compounded transformed shapes with the support
|
||||
TopoDS_Shape result;
|
||||
TopoDS_Shape current = support;
|
||||
|
||||
if (fuse) {
|
||||
BRepAlgoAPI_Fuse mkFuse(current, compoundTool);
|
||||
if (!mkFuse.IsDone())
|
||||
return new App::DocumentObjectExecReturn("Fusion with support failed", *o);
|
||||
// we have to get the solids (fuse sometimes creates compounds)
|
||||
current = this->getSolid(mkFuse.Shape());
|
||||
// lets check if the result is a solid
|
||||
if (current.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Resulting shape is not a solid", *o);
|
||||
std::vector<TopoDS_Shape>::const_iterator individualIt;
|
||||
for (individualIt = individualTools.begin(); individualIt != individualTools.end(); ++individualIt)
|
||||
{
|
||||
BRepAlgoAPI_Fuse mkFuse2(current, *individualIt);
|
||||
if (!mkFuse2.IsDone())
|
||||
return new App::DocumentObjectExecReturn("Fusion with support failed", *o);
|
||||
// we have to get the solids (fuse sometimes creates compounds)
|
||||
current = this->getSolid(mkFuse2.Shape());
|
||||
// lets check if the result is a solid
|
||||
if (current.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Resulting shape is not a solid", *o);
|
||||
}
|
||||
} else {
|
||||
BRepAlgoAPI_Cut mkCut(current, compoundTool);
|
||||
if (!mkCut.IsDone())
|
||||
return new App::DocumentObjectExecReturn("Cut out of support failed", *o);
|
||||
current = mkCut.Shape();
|
||||
std::vector<TopoDS_Shape>::const_iterator individualIt;
|
||||
for (individualIt = individualTools.begin(); individualIt != individualTools.end(); ++individualIt)
|
||||
{
|
||||
BRepAlgoAPI_Cut mkCut2(current, *individualIt);
|
||||
if (!mkCut2.IsDone())
|
||||
return new App::DocumentObjectExecReturn("Cut out of support failed", *o);
|
||||
current = this->getSolid(mkCut2.Shape());
|
||||
if (current.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Resulting shape is not a solid", *o);
|
||||
}
|
||||
}
|
||||
support = current; // Use result of this operation for fuse/cut of next original
|
||||
}
|
||||
support = refineShapeIfActive(support);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user