Shape Healing - Skip internal and external edges in ShapeAnalysis_FreeBounds (#1408)

- free bounds should be built from boundary edges only
- ignore edges with INTERNAL and EXTERNAL orientation in ConnectEdgesToWires()
This commit is contained in:
Pasukhin Dmitry
2026-07-30 00:01:25 +01:00
committed by GitHub
parent 72f14ee359
commit 50314b6938
3 changed files with 30 additions and 5 deletions
@@ -244,7 +244,7 @@ TEST(ShapeAnalysis_FreeBoundsTest, ConnectEdges_InternalEdgeAfterManifoldEdges)
occ::handle<NCollection_HSequence<TopoDS_Shape>> aResult =
ShapeAnalysis_FreeBounds::ConnectEdgesToWires(anInput, Precision::Confusion(), true);
checkResult(aResult, 2, 4, 1, 0, true);
checkResult(aResult, 1, 3, 0, 0, true);
}
TEST(ShapeAnalysis_FreeBoundsTest, ConnectEdges_InternalEdgeBeforeManifoldEdges)
@@ -260,7 +260,23 @@ TEST(ShapeAnalysis_FreeBoundsTest, ConnectEdges_InternalEdgeBeforeManifoldEdges)
occ::handle<NCollection_HSequence<TopoDS_Shape>> aResult =
ShapeAnalysis_FreeBounds::ConnectEdgesToWires(anInput, Precision::Confusion(), true);
checkResult(aResult, 2, 4, 1, 0, true);
checkResult(aResult, 1, 3, 0, 0, true);
}
TEST(ShapeAnalysis_FreeBoundsTest, ConnectEdges_ExternalEdgeIsSkipped)
{
TestData aData;
ASSERT_TRUE(makeTestData(aData));
occ::handle<NCollection_HSequence<TopoDS_Shape>> anInput =
new NCollection_HSequence<TopoDS_Shape>();
anInput->Append(aData.Edge1);
anInput->Append(aData.Edge2);
anInput->Append(aData.Edge3);
anInput->Append(aData.ExternalEdge);
occ::handle<NCollection_HSequence<TopoDS_Shape>> aResult =
ShapeAnalysis_FreeBounds::ConnectEdgesToWires(anInput, Precision::Confusion(), true);
checkResult(aResult, 1, 3, 0, 0, true);
}
// Baseline: a single closed face alone does not trigger the bug (see below).
@@ -36,8 +36,8 @@
#include <ShapeExtend_Explorer.hxx>
#include <ShapeExtend_WireData.hxx>
#include <NCollection_Array1.hxx>
#include <NCollection_LinearVector.hxx>
#include <Standard_Integer.hxx>
#include <NCollection_Sequence.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
@@ -137,25 +137,33 @@ occ::handle<NCollection_HSequence<TopoDS_Shape>> ShapeAnalysis_FreeBounds::Conne
const bool shared)
{
occ::handle<NCollection_HSequence<TopoDS_Shape>> iwires = new NCollection_HSequence<TopoDS_Shape>;
NCollection_LinearVector<int> anEdgeIndices;
BRep_Builder B;
int i; // svv #1
for (i = 1; i <= edges->Length(); i++)
{
const TopAbs_Orientation anOrientation = edges->Value(i).Orientation();
if (anOrientation == TopAbs_INTERNAL || anOrientation == TopAbs_EXTERNAL)
{
continue;
}
TopoDS_Wire wire;
B.MakeWire(wire);
B.Add(wire, edges->Value(i));
iwires->Append(wire);
anEdgeIndices.Append(i);
}
occ::handle<NCollection_HSequence<TopoDS_Shape>> wires =
ConnectWiresToWires(iwires, toler, shared);
for (i = 1; i <= edges->Length(); i++)
for (i = 1; i <= iwires->Length(); i++)
{
if (iwires->Value(i).Orientation() == TopAbs_REVERSED)
{
edges->ChangeValue(i).Reverse();
edges->ChangeValue(anEdgeIndices[i - 1]).Reverse();
}
}
@@ -110,6 +110,7 @@ public:
//! at its tail.
//!
//! Orientation of the edge can change when connecting.
//! Edges having INTERNAL or EXTERNAL orientation are ignored.
//! If <shared> is True connection is performed only when
//! adjacent edges share the same vertex.
//! If <shared> is False connection is performed only when