1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0027082: UnifySameDomain must add internal edges where appropriate to resolve self-intersections

The new option AllowInternalEdges has been added in the class ShapeUpgrade_UnifySameDomain. It determines how the algorithm treats the situation when two faces can be merged together but they have connection with another face via the common edge.

With this option turned on, merging of such faces is not stopped, but the multiconnected edges are added to the merged face as INTERNAL edges.

By default it is false. In this mode such merging is forbidden, so the result shape will not contain any new INTERNAL edges.

The behavior of the algorithm has been changed so that it does not merge faces from different shells.
This commit is contained in:
msv
2016-03-22 15:23:00 +03:00
committed by bugmaster
parent 6220ba10a3
commit fe1a6e4e54
10 changed files with 215 additions and 37 deletions

View File

@@ -641,11 +641,11 @@ static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& aChain, Topo
}
if (Abs(FP) < Precision::PConfusion())
{
B.MakeEdge (E,Cir, Precision::Confusion());
B.Add(E,V1);
B.Add(E,V2);
E.Orientation(FE.Orientation());
}
B.MakeEdge (E,Cir,Precision::Confusion());
B.Add(E,V1);
B.Add(E,V2);
E.Orientation(FE.Orientation());
}
else
{
GC_MakeCircle MC1 (adef.Value(FP), adef.Value((FP + LP) * 0.5), adef.Value(LP));
@@ -988,11 +988,11 @@ static void CheckSharedVertices(const TopTools_SequenceOfShape& theSeqEdges,
//=======================================================================
ShapeUpgrade_UnifySameDomain::ShapeUpgrade_UnifySameDomain()
: myUnifyFaces (Standard_True),
myUnifyEdges (Standard_True),
myConcatBSplines (Standard_False),
myAllowInternal (Standard_False)
{
myUnifyEdges = Standard_True;
myUnifyFaces = Standard_True;
myConcatBSplines = Standard_False;
myContext = new ShapeBuild_ReShape;
}
@@ -1005,13 +1005,13 @@ ShapeUpgrade_UnifySameDomain::ShapeUpgrade_UnifySameDomain(const TopoDS_Shape& a
const Standard_Boolean UnifyEdges,
const Standard_Boolean UnifyFaces,
const Standard_Boolean ConcatBSplines)
: myInitShape (aShape),
myUnifyFaces (UnifyFaces),
myUnifyEdges (UnifyEdges),
myConcatBSplines (ConcatBSplines),
myAllowInternal (Standard_False),
myShape (aShape)
{
myInitShape = aShape;
myShape = aShape;
myUnifyEdges = UnifyEdges;
myUnifyFaces = UnifyFaces;
myConcatBSplines = ConcatBSplines;
myContext = new ShapeBuild_ReShape;
}
@@ -1033,7 +1033,16 @@ void ShapeUpgrade_UnifySameDomain::Initialize(const TopoDS_Shape& aShape,
myContext->Clear();
myOldShapes.Clear();
//myGenerated.Clear();
}
//=======================================================================
//function : AllowInternalEdges
//purpose :
//=======================================================================
void ShapeUpgrade_UnifySameDomain::AllowInternalEdges (const Standard_Boolean theValue)
{
myAllowInternal = theValue;
}
//=======================================================================
@@ -1074,14 +1083,19 @@ static void putIntWires(TopoDS_Shape& theFace, TopTools_SequenceOfShape& theWire
void ShapeUpgrade_UnifySameDomain::UnifyFaces()
{
// creating map of edge faces
TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
// creating map of edge faces for the whole shape
TopTools_IndexedDataMapOfShapeListOfShape aGMapEdgeFaces;
TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, aGMapEdgeFaces);
// processing each shell
TopExp_Explorer exps;
for (exps.Init(myShape, TopAbs_SHELL); exps.More(); exps.Next()) {
TopoDS_Shell aShell = TopoDS::Shell(exps.Current());
// creating map of edge faces for the shell
TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
// map of processed shapes
TopTools_MapOfShape aProcessed;
@@ -1125,6 +1139,13 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces()
if (BRep_Tool::Degenerated(edge))
continue;
// get connectivity of the edge in the global shape
const TopTools_ListOfShape& aGList = aGMapEdgeFaces.FindFromKey(edge);
if (!myAllowInternal && aGList.Extent() != 2) {
// non mainfold case is not processed unless myAllowInternal
continue;
}
// process faces connected through the edge in the current shell
const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge);
TopTools_ListIteratorOfListOfShape anIter(aList);
for (; anIter.More(); anIter.Next()) {
@@ -1137,11 +1158,6 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces()
if (IsSameDomain(aFace,anCheckedFace)) {
if (aList.Extent() != 2) {
// non mainfold case is not processed
continue;
}
// replacing pcurves
TopoDS_Face aMockUpFace;
BRep_Builder B;
@@ -1160,6 +1176,55 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces()
}
}
if (faces.Length() > 1) {
// fill in the connectivity map for selected faces
TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
for (i = 1; i <= faces.Length(); i++) {
TopExp::MapShapesAndAncestors(faces(i), TopAbs_EDGE, TopAbs_FACE, aMapEF);
}
// Collect multiconnected edges, i.e. edges that are internal to
// the set of selected faces and have connections to other faces.
TopTools_ListOfShape aMultEdges;
for (i = 1; i <= aMapEF.Extent(); i++) {
const TopTools_ListOfShape& aLF = aMapEF(i);
if (aLF.Extent() == 2) {
const TopoDS_Shape& aE = aMapEF.FindKey(i);
const TopTools_ListOfShape& aGLF = aGMapEdgeFaces.FindFromKey(aE);
if (aGLF.Extent() > 2) {
aMultEdges.Append(aE);
}
}
}
if (!aMultEdges.IsEmpty()) {
if (!myAllowInternal) {
// Remove from the selection the faces containing multiconnected edges
TopTools_MapOfShape anAvoidFaces;
TopTools_ListIteratorOfListOfShape it(aMultEdges);
for (; it.More(); it.Next()) {
const TopoDS_Shape& aE = it.Value();
const TopTools_ListOfShape& aLF = aMapEF.FindFromKey(aE);
anAvoidFaces.Add(aLF.First());
anAvoidFaces.Add(aLF.Last());
}
for (i = 1; i <= faces.Length(); ) {
if (anAvoidFaces.Contains(faces(i)))
faces.Remove(i);
else
i++;
}
}
else {
// add multiconnected edges as internal in new face
TopTools_ListIteratorOfListOfShape it(aMultEdges);
for (; it.More(); it.Next()) {
const TopoDS_Shape& aE = it.Value();
edges.Append(aE.Oriented(TopAbs_INTERNAL));
}
}
}
}
// all faces collected in the sequence. Perform union of faces
if (faces.Length() > 1) {
NbModif++;
@@ -1359,11 +1424,11 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces()
}
else
{
Handle(ShapeExtend_WireData) sbwd =
Handle(ShapeExtend_WireData) sbwd =
new ShapeExtend_WireData (aWire);
ShapeFix_WireSegment seg ( sbwd, TopAbs_REVERSED );
wires.Append(seg);
}
ShapeFix_WireSegment seg ( sbwd, TopAbs_REVERSED );
wires.Append(seg);
}
}
CompShell.DispatchWires ( parts,wires );