1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-21 10:13:43 +03:00

0029502: Improve performance of the ShapeUpgrade_UnifySameDomain::UnifyEdges() method

Avoid repeated merging of the same chains of edges by processing all edges at once.

Test cases for the issue.
This commit is contained in:
emv 2018-02-13 15:01:39 +03:00 committed by apn
parent db60634ed1
commit 12d71ad6a5
5 changed files with 115 additions and 102 deletions

View File

@ -1645,122 +1645,48 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
void ShapeUpgrade_UnifySameDomain::UnifyEdges() void ShapeUpgrade_UnifySameDomain::UnifyEdges()
{ {
TopoDS_Shape aRes = myContext->Apply(myShape); TopoDS_Shape aRes = myContext->Apply(myShape);
TopTools_IndexedMapOfShape ChangedFaces;
// creating map of edge faces // creating map of edge faces
TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces; TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
TopExp::MapShapesAndAncestors(aRes, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces); TopExp::MapShapesAndAncestors(aRes, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
// creating map of vertex edges // creating map of vertex edges
TopTools_IndexedDataMapOfShapeListOfShape aMapEdgesVertex; TopTools_IndexedDataMapOfShapeListOfShape aMapEdgesVertex;
TopExp::MapShapesAndUniqueAncestors(aRes, TopAbs_VERTEX, TopAbs_EDGE, aMapEdgesVertex); TopExp::MapShapesAndUniqueAncestors(aRes, TopAbs_VERTEX, TopAbs_EDGE, aMapEdgesVertex);
TopTools_MapOfShape SharedVert;
TopTools_IndexedMapOfShape anOldEdges;
TopExp::MapShapes(myInitShape, TopAbs_EDGE, anOldEdges);
TopTools_DataMapOfShapeShape NewEdges2OldEdges;
for (int i = 1; i <= anOldEdges.Extent(); i++)
{
const TopoDS_Shape& anOldEdge = anOldEdges(i);
TopoDS_Shape aNewEdge = myContext->Apply(anOldEdge);
if (!aNewEdge.IsNull() && !aNewEdge.IsSame(anOldEdge))
NewEdges2OldEdges.Bind(aNewEdge, anOldEdge);
}
if (mySafeInputMode) if (mySafeInputMode)
UpdateMapOfShapes(myKeepShapes, myContext); UpdateMapOfShapes(myKeepShapes, myContext);
TopExp_Explorer exp; // Sequence of the edges of the shape
// processing separate wires TopTools_SequenceOfShape aSeqEdges;
for (exp.Init(aRes, TopAbs_WIRE, TopAbs_FACE); exp.More(); exp.Next()) const Standard_Integer aNbE = aMapEdgeFaces.Extent();
{ for (Standard_Integer i = 1; i <= aNbE; ++i)
TopTools_SequenceOfShape SeqEdges; aSeqEdges.Append(aMapEdgeFaces.FindKey(i));
TopExp_Explorer expE(exp.Current(), TopAbs_EDGE);
for (; expE.More(); expE.Next())
SeqEdges.Append(expE.Current());
SharedVert.Clear();
CheckSharedVertices(SeqEdges, aMapEdgesVertex, myKeepShapes, SharedVert);
MergeSeq(SeqEdges, myAngTol, myLinTol, myConcatBSplines, mySafeInputMode, myContext,
SharedVert);
}
// processing each face // Prepare map of shared vertices (with the number of connected edges greater then 2)
for (exp.Init(aRes, TopAbs_FACE); exp.More(); exp.Next()) { TopTools_MapOfShape aSharedVert;
TopoDS_Shape aFace = exp.Current().Oriented(TopAbs_FORWARD); CheckSharedVertices(aSeqEdges, aMapEdgesVertex, myKeepShapes, aSharedVert);
TopTools_IndexedDataMapOfShapeListOfShape aMapFacesEdges; // Merge the edges avoiding removal of the shared vertices
TopTools_SequenceOfShape aNonSharedEdges; Standard_Boolean isMerged = MergeSeq(aSeqEdges, myAngTol, myLinTol, myConcatBSplines,
for (TopExp_Explorer expe(aFace,TopAbs_EDGE); expe.More(); expe.Next()) { mySafeInputMode, myContext, aSharedVert);
TopoDS_Edge edge = TopoDS::Edge(expe.Current()); // Collect faces to rebuild
const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge); TopTools_IndexedMapOfShape aChangedFaces;
TopTools_ListIteratorOfListOfShape anIter(aList); if (isMerged)
Standard_Integer NbFacesPerEdge = aList.Extent();
for ( ; anIter.More(); anIter.Next()) {
const TopoDS_Shape& aFace1 = anIter.Value();
if (aFace1.IsSame(aFace) && NbFacesPerEdge != 1)
continue;
if (NbFacesPerEdge == 1)
//store non-shared edges separately
aNonSharedEdges.Append(edge);
else
{ {
if (aMapFacesEdges.Contains(aFace1)) for (Standard_Integer i = 1; i <= aNbE; ++i)
aMapFacesEdges.ChangeFromKey(aFace1).Append(edge);
else
{ {
TopTools_ListOfShape ListEdges; const TopoDS_Shape& aE = aMapEdgeFaces.FindKey(i);
ListEdges.Append(edge); if (myContext->IsRecorded(aE))
aMapFacesEdges.Add(aFace1, ListEdges);
}
}
}
}
for (Standard_Integer i=1; i<=aMapFacesEdges.Extent(); i++)
{ {
const TopTools_ListOfShape& ListEdges = aMapFacesEdges.FindFromIndex(i); TopTools_ListIteratorOfListOfShape it(aMapEdgeFaces(i));
TopTools_SequenceOfShape SeqEdges; for (; it.More(); it.Next())
TopTools_ListIteratorOfListOfShape anIter(ListEdges); aChangedFaces.Add(it.Value());
for ( ; anIter.More(); anIter.Next())
SeqEdges.Append(anIter.Value());
if (SeqEdges.Length()==1)
continue;
SharedVert.Clear();
CheckSharedVertices(SeqEdges, aMapEdgesVertex, myKeepShapes, SharedVert);
if (MergeSeq(SeqEdges, myAngTol, myLinTol, myConcatBSplines, mySafeInputMode,
myContext, SharedVert))
{
TopoDS_Face tmpF = TopoDS::Face(exp.Current());
if ( !ChangedFaces.Contains(tmpF) )
ChangedFaces.Add(tmpF);
tmpF = TopoDS::Face(aMapFacesEdges.FindKey(i));
if ( !ChangedFaces.Contains(tmpF) )
ChangedFaces.Add(tmpF);
} }
} }
if ( aNonSharedEdges.Length() > 1 )
{
SharedVert.Clear();
CheckSharedVertices(aNonSharedEdges, aMapEdgesVertex, myKeepShapes, SharedVert);
if (MergeSeq(aNonSharedEdges, myAngTol, myLinTol, myConcatBSplines, mySafeInputMode,
myContext, SharedVert))
{
TopoDS_Face tmpF = TopoDS::Face(exp.Current());
if ( !ChangedFaces.Contains(tmpF) )
ChangedFaces.Add(tmpF);
} }
}
} // end processing each face
// fix changed faces and replace them in the local context // fix changed faces and replace them in the local context
Standard_Real aPrec = Precision::Confusion(); Standard_Real aPrec = Precision::Confusion();
for (Standard_Integer i = 1; i <= ChangedFaces.Extent(); i++) { for (Standard_Integer i = 1; i <= aChangedFaces.Extent(); i++) {
TopoDS_Face aFace = TopoDS::Face(myContext->Apply(ChangedFaces.FindKey(i))); TopoDS_Face aFace = TopoDS::Face(myContext->Apply(aChangedFaces.FindKey(i)));
if (aFace.IsNull()) if (aFace.IsNull())
continue; continue;
@ -1798,7 +1724,7 @@ void ShapeUpgrade_UnifySameDomain::UnifyEdges()
myContext->Replace(aFace,aNewFace); myContext->Replace(aFace,aNewFace);
} }
if (ChangedFaces.Extent() > 0) { if (aChangedFaces.Extent() > 0) {
// fix changed shell and replace it in the local context // fix changed shell and replace it in the local context
TopoDS_Shape aRes1 = myContext->Apply(aRes); TopoDS_Shape aRes1 = myContext->Apply(aRes);
Standard_Boolean isChanged = Standard_False; Standard_Boolean isChanged = Standard_False;

View File

@ -0,0 +1,30 @@
puts "========"
puts "OCC29502"
puts "========"
puts ""
#################################################
# Improve performance of the ShapeUpgrade_UnifySameDomain::UnifyEdges() method
#################################################
# create cylinder
cylinder c 0 0 0 0 0 1 10
mkface f c 0 2*pi -10 10
# split seam edge by the vertex
vertex v 10 0 0
bclearobjects
bcleartools
baddobjects f
baddtools v
bfillds
bsplit r
explode r f
# perform unification of the seam edge:
# the split vertex should be removed
unifysamedom result r_1
checkshape result
checkprops result -equal f
checknbshapes result -ref [nbshapes f]

View File

@ -0,0 +1,19 @@
puts "============"
puts "OCC29502"
puts "============"
puts ""
###############################
## Improve performance of the ShapeUpgrade_UnifySameDomain::UnifyEdges() method
###############################
restore [locate_data_file bug29502_faces.brep] cf
dchrono h restart
unifysamedom result cf +b
dchrono h stop counter unifysamedom
checkshape result
checkprops result -equal cf -skip
checknbshapes result -vertex 146 -edge 217 -wire 72 -face 72 -t

View File

@ -0,0 +1,19 @@
puts "============"
puts "OCC29502"
puts "============"
puts ""
###############################
## Improve performance of the ShapeUpgrade_UnifySameDomain::UnifyEdges() method
###############################
restore [locate_data_file bug29502_split_faces.brep] cf
dchrono h restart
unifysamedom result cf -f +b
dchrono h stop counter unifysamedom
checkshape result
checkprops result -equal cf -skip
checknbshapes result -vertex 365 -edge 652 -wire 288 -face 288 -t

View File

@ -0,0 +1,19 @@
puts "============"
puts "OCC29502"
puts "============"
puts ""
###############################
## Improve performance of the ShapeUpgrade_UnifySameDomain::UnifyEdges() method
###############################
restore [locate_data_file bug29502_split_faces.brep] cf
dchrono h restart
unifysamedom result cf +b
dchrono h stop counter unifysamedom
checkshape result
checkprops result -l 2900 -s 14400 -skip
checknbshapes result -vertex 146 -edge 217 -wire 72 -face 72 -t