0028600: Bad performance of the checkshape command IR-2017-03-30
authoraml <aml@opencascade.com>
Tue, 28 Mar 2017 03:52:24 +0000 (06:52 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 30 Mar 2017 11:04:26 +0000 (14:04 +0300)
Shell check has been improved to use well-known width-first search. It significantly reduces computation time on the big shells.

Test case has been added.

Minor correction in test case

src/BRepCheck/BRepCheck_Shell.cxx
tests/perf/modalg/bug28600 [new file with mode: 0644]

index 1cd78e0..ec63eae 100644 (file)
@@ -44,51 +44,37 @@ IMPLEMENT_STANDARD_RTTIEXT(BRepCheck_Shell,BRepCheck_Result)
 //purpose  : 
 //=======================================================================
 static void Propagate(const TopTools_IndexedDataMapOfShapeListOfShape& mapEF,
-                     const TopoDS_Shape& theFac,
-                     TopTools_MapOfShape& mapF)
+                      const TopoDS_Shape& theFace,
+                      TopTools_IndexedMapOfShape& theMapF)
 {
-  if (mapF.Contains(theFac))
-  {
-    return;
-  }
-  mapF.Add(theFac);  // attention, if oriented == Standard_True, fac should
-                  // be FORWARD or REVERSED. It is not checked.
+  // Base for the traverse procedure.
+  theMapF.Add(theFace);
 
-  TopTools_MapIteratorOfMapOfShape itf(mapF);
-  while(itf.More())
+  // Perform well-known width-first traverse.
+  for (Standard_Integer anIdx = 1; anIdx <= theMapF.Extent(); ++anIdx)
   {
-    Standard_Boolean hasBeenAdded = Standard_False;
-    const TopoDS_Shape& fac = itf.Key();
-    TopExp_Explorer ex;
-    for (ex.Init(fac,TopAbs_EDGE); ex.More(); ex.Next())
+    const TopoDS_Shape& aFace = theMapF(anIdx);
+    for (TopExp_Explorer ex(aFace, TopAbs_EDGE); ex.More(); ex.Next())
     {
       const TopoDS_Edge& edg = TopoDS::Edge(ex.Current());
-      // test if the edge is in the map (only orienteed edges are present)
-      if (mapEF.Contains(edg))
+
+      // Test if the edge is in the map (only oriented edges are present).
+      const TopTools_ListOfShape* aList = mapEF.Seek(edg);
+
+      if ( aList == NULL )
+        continue;
+
+      for (TopTools_ListIteratorOfListOfShape itl(*aList); itl.More(); itl.Next())
       {
-        for (TopTools_ListIteratorOfListOfShape itl(mapEF.FindFromKey(edg)); itl.More(); itl.Next())
-        {
-          if (!itl.Value().IsSame(fac) && !mapF.Contains(itl.Value()))
-          {
-            mapF.Add(itl.Value());
-            hasBeenAdded = Standard_True;
-          }
-        }
+        // This code assumes that shape is added to an end of the map.
+        // The idea is simple: existing objects will not be added, new objects
+        // will be added to an end.
+        theMapF.Add(itl.Value());
       }
-    }//for (ex.Init(fac,TopAbs_EDGE); ex.More();)
-
-    if(hasBeenAdded)
-    {
-      itf.Initialize(mapF);
-    }
-    else
-    {
-      itf.Next();
     }
   }
 }
 
-
 //=======================================================================
 //function : BRepCheck_Trace
 //purpose  : 
@@ -218,7 +204,7 @@ void BRepCheck_Shell::Minimum()
     }
     else if (nbface >= 2)
     {
-      TopTools_MapOfShape mapF;
+      TopTools_IndexedMapOfShape mapF;
       exp.ReInit();
 
       Propagate(myMapEF,exp.Current(),mapF);
@@ -338,7 +324,8 @@ BRepCheck_Status BRepCheck_Shell::Closed(const Standard_Boolean Update)
   //
   Standard_Integer index, aNbF;
   TopExp_Explorer exp, ede;
-  TopTools_MapOfShape mapS, aMEToAvoid;
+  TopTools_IndexedMapOfShape mapS;
+  TopTools_MapOfShape aMEToAvoid;
   myMapEF.Clear();
   
 
diff --git a/tests/perf/modalg/bug28600 b/tests/perf/modalg/bug28600
new file mode 100644 (file)
index 0000000..51a6b38
--- /dev/null
@@ -0,0 +1,19 @@
+puts "REQUIRED All: Faulty shapes in variables faulty_1 to faulty_"
+puts "========"
+puts "OCC28600"
+puts "========"
+puts ""
+########################################################################################################
+# Bad performance of the checkshape command
+########################################################################################################
+
+pload ALL
+
+# Read shape.
+testreadstep [locate_data_file bug28600.stp] s1
+
+# Measure performance metrics.
+chrono s reset; chrono s start;
+checkshape s1
+chrono s stop counter checkshape; chrono s show;
+