0028467: Improve UnifySameDomain performance
authormsv <msv@opencascade.com>
Fri, 17 Feb 2017 08:26:25 +0000 (11:26 +0300)
committerbugmaster <bugmaster@opencascade.com>
Tue, 14 Nov 2017 12:56:53 +0000 (15:56 +0300)
This patch turns off some not needed modes of fix in the called ShapeFix_Face algorithm.

It stores pcurves on planes in the edges to avoid repeated computation of the same pcurves many times (it is done only when SafeInputMode is false).

It avoids unnecessary replace/apply actions in the modification context.

It removes the code that makes decomposition of surface of the face on several faces.

The new command buildpcurvesonplane has been added, which builds and stores pcurves of edges on planar faces. This is useful for investigations how presence of pcurves on planes influence performance of algorithms.

Make drawing of dimension line in snowflake test independent on the order of vertices in the result.

20 files changed:
dox/dev_guides/upgrade/upgrade.md
samples/tcl/snowflake.tcl
src/BOPAlgo/BOPAlgo_Builder_2.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx
src/BOPAlgo/BOPAlgo_Tools.cxx
src/BOPTest/BOPTest_UtilityCommands.cxx
src/BOPTools/BOPTools_AlgoTools2D.cxx
src/BOPTools/BOPTools_AlgoTools2D.hxx
src/BRep/BRep_Tool.cxx
src/BRep/BRep_Tool.hxx
src/BRepLib/BRepLib.hxx
src/BRepLib/BRepLib_1.cxx
src/BRepOffset/BRepOffset_MakeOffset_1.cxx
src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx
src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx
tests/heal/unify_same_domain/A4
tests/heal/unify_same_domain/A9
tests/perf/heal/bug28467_1 [new file with mode: 0644]
tests/perf/heal/bug28467_2 [new file with mode: 0644]
tests/perf/heal/bug28467_3 [new file with mode: 0644]

index 9593116..cee4fc8 100644 (file)
@@ -1437,3 +1437,19 @@ The Error/Warning reporting system of the algorithms in Boolean Component (in al
 The methods returning the status of errors and warnings of the algorithms (ErrorStatus() and WarningStatus()) have been removed.
 Instead use methods HasErrors() and HasWarnings() to check for presence of errors and warnings, respectively.
 The full list of errors and warnings, with associated data such as problematic sub-shapes, can be obtained by method GetReport().
+
+@section upgrade_occt721 Upgrade to OCCT 7.2.1
+
+@subsection upgrade_721_Changes_In_USD Changes in ShapeUpgrade_UnifySameDomain
+
+The following public methods in the class ShapeUpgrade_UnifySameDomain became protected:
+* *UnifyFaces*
+* *UnifyEdges*
+
+The following public method has been removed:
+* *UnifyFacesAndEdges*
+
+@subsection upgrade_721_Move_BuildPCurveForEdgeOnPlane Moving BuildPCurveForEdgeOnPlane from BOPTools_AlgoTools2D to BRepLib
+
+The methods BuildPCurveForEdgeOnPlane and BuildPCurveForEdgesOnPlane have been moved from the class BOPTools_AlgoTools2D
+to the more lower level class BRepLib.
index bfafc0e..06eb89f 100644 (file)
@@ -135,9 +135,32 @@ vsetcolorbg 255 255 255
 vtop
 vfit
 
-# add dimension
-explode snowflake v
-vdimension length -length -shapes snowflake_89 snowflake_15 -plane xoy -value 0.001 -dispunits mm -showunits -flyout 70 -label above -color black -text 5 3d sh
+# add dimension:
+# detect vertices extremal in X direction
+boundingstr snowflake x1 y1 z1 x2 y2 z2
+plane f1 x1 0 0 1 0 0
+plane f2 x2 0 0 1 0 0
+mkface f1 f1
+mkface f2 f2
+bsection s1 snowflake f1
+bsection s2 snowflake f2
+# select only upper vertices (nearer to the upper bound)
+explode s1 v
+explode s2 v
+plane fup 0 y2 0 0 1 0
+mkface fup fup
+for {set i 1} {$i <= 2} {incr i} {
+  set dmin 1e10
+  for {set j 1} {$j <= 2} {incr j} {
+    distmini d s${i}_$j fup
+    set dist [dval d_val]
+    if {$dmin > $dist} {
+      set dmin $dist
+      eval set v$i s${i}_$j
+    }
+  }
+}
+vdimension length -length -shapes $v1 $v2 -plane xoy -value 0.001 -dispunits mm -showunits -flyout 70 -label above -color black -text 5 3d sh
 
 if { [regexp HAVE_GL2PS [dversion]] } {
     puts "You can use command vexport to generate PDF: vexport your_file_path.pdf"
index c818e16..b067c2b 100644 (file)
@@ -45,6 +45,7 @@
 #include <BOPTools_ListOfCoupleOfShape.hxx>
 #include <BOPTools_MapOfSet.hxx>
 #include <BRep_Builder.hxx>
+#include <BRepLib.hxx>
 #include <BRep_Tool.hxx>
 #include <GeomAdaptor_Surface.hxx>
 #include <GeomLib.hxx>
@@ -438,7 +439,7 @@ void BOPAlgo_Builder::BuildSplitFaces()
     //
     if (!myPaveFiller->NonDestructive()) {
       // speed up for planar faces
-      BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane (aLE, aFF);
+      BRepLib::BuildPCurveForEdgesOnPlane(aLE, aFF);
     }
     // 3 Build split faces
     BOPAlgo_BuilderFace& aBF=aVBF.Append1();
index 20175df..ab50205 100644 (file)
@@ -40,6 +40,7 @@
 #include <BOPDS_VectorOfListOfPaveBlock.hxx>
 #include <BOPTools_AlgoTools.hxx>
 #include <BOPTools_AlgoTools2D.hxx>
+#include <BRepLib.hxx>
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
 #include <BRepBndLib.hxx>
@@ -365,7 +366,7 @@ class BOPAlgo_BPC {
   }
   //
   void Perform() {
-    BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (myE, myF, myCurve, myToUpdate);
+    BRepLib::BuildPCurveForEdgeOnPlane(myE, myF, myCurve, myToUpdate);
   };
   //
  protected:
index d91da14..4a4484a 100644 (file)
@@ -44,6 +44,7 @@
 
 #include <BRepBuilderAPI_MakeFace.hxx>
 
+#include <BRepLib.hxx>
 #include <BRep_Tool.hxx>
 #include <BRep_Builder.hxx>
 
@@ -659,7 +660,7 @@ Standard_Boolean BOPAlgo_Tools::WiresToFaces(const TopoDS_Shape& theWires,
       OCC_CATCH_SIGNALS
       //
       // build pcurves for edges on this face
-      BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane(aLE, aFF);
+      BRepLib::BuildPCurveForEdgesOnPlane(aLE, aFF);
       //
       // split the face with the edges
       BOPAlgo_BuilderFace aBF;
index 92b4a7e..dab78df 100644 (file)
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Shape.hxx>
+#include <TopExp_Explorer.hxx>
 #include <Draw.hxx>
 #include <BOPAlgo_Tools.hxx>
+#include <BRepLib.hxx>
 
 static Standard_Integer attachpcurve (Draw_Interpretor&, Standard_Integer, const char**);
 static Standard_Integer edgestowire  (Draw_Interpretor&, Standard_Integer, const char**);
 static Standard_Integer edgestofaces  (Draw_Interpretor&, Standard_Integer, const char**);
+static Standard_Integer BuildPcurvesOnPlane(Draw_Interpretor&, Standard_Integer, const char**);
 
 //=======================================================================
 //function : BOPCommands
@@ -46,7 +49,8 @@ static Standard_Integer edgestofaces  (Draw_Interpretor&, Standard_Integer, cons
   theCommands.Add("attachpcurve", "attachpcurve eold enew face", __FILE__, attachpcurve, group);
   theCommands.Add("edgestowire" , "edgestowire wire edges"     , __FILE__, edgestowire , group);
   theCommands.Add("edgestofaces" , "edgestofaces faces edges [-a AngTol -s Shared(0/1)]", __FILE__, edgestofaces , group);
-}
+  theCommands.Add("buildpcurvesonplane", "buildpcurvesonplane shape", __FILE__, BuildPcurvesOnPlane, group);
+  }
 
 //=======================================================================
 //function : BOPCommands
@@ -183,3 +187,40 @@ static Standard_Integer edgestofaces(Draw_Interpretor& theDI,
   DBRep::Set(theArgVal[1], aFaces);
   return 0;
 }
+
+//=======================================================================
+//function : BuildPcurvesOnPlane
+//purpose  : Build and store pcurves of edges on planes
+//=======================================================================
+static Standard_Integer BuildPcurvesOnPlane(Draw_Interpretor& theDI,
+                                 Standard_Integer  theNArg,
+                                 const char ** theArgVal)
+{
+  if (theNArg != 2)
+  {
+    theDI << "Use: " << theArgVal[0] << " shape\n";
+    return 1;
+  }
+
+  TopoDS_Shape aShape(DBRep::Get(theArgVal[1]));
+  if (aShape.IsNull()) {
+    theDI << theArgVal[1] << " is null shape\n";
+    return 1;
+  }
+
+  TopExp_Explorer exp(aShape, TopAbs_FACE);
+  for (; exp.More(); exp.Next())
+  {
+    const TopoDS_Face& aF = TopoDS::Face(exp.Current());
+    BRepAdaptor_Surface aS(aF, Standard_False);
+    if (aS.GetType() == GeomAbs_Plane)
+    {
+      BOPCol_ListOfShape aLE;
+      TopExp_Explorer exp1(aF, TopAbs_EDGE);
+      for (; exp1.More(); exp1.Next())
+        aLE.Append(exp1.Current());
+      BRepLib::BuildPCurveForEdgesOnPlane(aLE, aF);
+    }
+  }
+  return 0;
+}
index 9e41adb..d8cfac6 100644 (file)
 #include <TopoDS_Face.hxx>
 
 static
-  Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& , 
-                                                const TopoDS_Face& ,
-                                                Standard_Real& ,
-                                                Standard_Real& ,
-                                                Standard_Boolean& );
-static
-  Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& , 
-                                                const Handle(Geom_Surface)& ,
-                                                const TopLoc_Location& ,
-                                                Standard_Real& ,
-                                                Standard_Real& ,
-                                                Standard_Boolean& );
-static
   Standard_Real MaxToleranceEdge (const TopoDS_Face& );
 
 //=======================================================================
@@ -473,57 +460,6 @@ Standard_Real BOPTools_AlgoTools2D::IntermediatePoint
   aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
   return aT;
 }
-
-//=======================================================================
-//function : BuildPCurveForEdgeOnPlane
-//purpose  : 
-//=======================================================================
-void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane 
-  (const TopoDS_Edge& aE,
-   const TopoDS_Face& aF)
-{
-  Standard_Boolean bToUpdate;
-  Standard_Real aTolE, aT1, aT2;
-  Handle(Geom2d_Curve) aC2D;
-  BRep_Builder aBB;
-  //
-  aC2D=BRep_Tool_CurveOnSurface(aE, aF, aT1, aT2, bToUpdate);
-  if (bToUpdate) {
-    aTolE=BRep_Tool::Tolerance(aE);
-    aBB.UpdateEdge(aE, aC2D, aF, aTolE);
-  }
-}
-
-//=======================================================================
-//function : BuildPCurveForEdgeOnPlane
-//purpose  : 
-//=======================================================================
-void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane 
-  (const TopoDS_Edge& aE,
-   const TopoDS_Face& aF,
-   Handle(Geom2d_Curve)& aC2D,
-   Standard_Boolean& bToUpdate)
-{
-  Standard_Real aT1, aT2;
-  aC2D=BRep_Tool_CurveOnSurface(aE, aF, aT1, aT2, bToUpdate);
-}
-
-//=======================================================================
-// function: BuildPCurveForEdgesOnPlane
-// purpose: 
-//=======================================================================
-void BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane 
-  (const BOPCol_ListOfShape& aLE,
-   const TopoDS_Face& aF)
-{
-  BOPCol_ListIteratorOfListOfShape aIt;
-  //
-  aIt.Initialize(aLE);
-  for(; aIt.More(); aIt.Next()) {
-    const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value());
-    BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (aE, aF);
-  }
-}
 //=======================================================================
 //function : Make2D
 //purpose  : 
@@ -704,124 +640,6 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace
 }
 
 //=======================================================================
-//function : BRep_Tool_CurveOnSurface
-//purpose  : 
-//=======================================================================
-Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& E, 
-                                              const TopoDS_Face& F,
-                                              Standard_Real& First,
-                                              Standard_Real& Last,
-                                              Standard_Boolean& bToUpdate)
-{
-  TopLoc_Location l;
-  const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l);
-  TopoDS_Edge aLocalEdge = E;
-  if (F.Orientation() == TopAbs_REVERSED) {
-    aLocalEdge.Reverse();
-  }
-  //
-  return BRep_Tool_CurveOnSurface(aLocalEdge,S,l,First,Last,bToUpdate);
-}
-//=======================================================================
-//function : BRep_Tool_CurveOnSurface
-//purpose  : 
-//=======================================================================
-Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface
-       (const TopoDS_Edge& E, 
-        const Handle(Geom_Surface)& S,
-        const TopLoc_Location& L,
-        Standard_Real& First,
-        Standard_Real& Last,
-        Standard_Boolean& bToUpdate)
-{
-  static const Handle(Geom2d_Curve) nullPCurve;
-  bToUpdate=Standard_False;
-  TopLoc_Location loc = L.Predivided(E.Location());
-  Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
-
-  // find the representation
-  BRep_ListIteratorOfListOfCurveRepresentation itcr
-    ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
-
-  while (itcr.More()) {
-    const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
-    if (cr->IsCurveOnSurface(S,loc)) {
-      Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
-      GC->Range(First,Last);
-      if (GC->IsCurveOnClosedSurface() && Eisreversed)
-        return GC->PCurve2();
-      else
-        return GC->PCurve();
-    }
-    itcr.Next();
-  }
-
-  // for planar surface and 3d curve try a projection
-  // modif 21-05-97 : for RectangularTrimmedSurface, try a projection
-  Handle(Geom_Plane) GP;
-  Handle(Geom_RectangularTrimmedSurface) GRTS;
-  GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
-  if(!GRTS.IsNull())
-    GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface());
-  else
-    GP = Handle(Geom_Plane)::DownCast(S);
-  //fin modif du 21-05-97
-
-  if (!GP.IsNull()) {
-
-    Handle(GeomAdaptor_HCurve) HC;
-    Handle(GeomAdaptor_HSurface) HS;
-
-    HC = new GeomAdaptor_HCurve();
-    HS = new GeomAdaptor_HSurface();
-
-    TopLoc_Location LC;
-
-    Standard_Real f, l;// for those who call with (u,u).
-    Handle(Geom_Curve) C3d =
-      BRep_Tool::Curve(E,/*LC,*/f,l); // transforming plane instead of curve
-    // we can loose scale factor of Curve transformation (eap 13 May 2002)
-
-    LC = L/*.Predivided(LC)*/;
-
-    if (C3d.IsNull()) return nullPCurve;
-
-    Handle(Geom_Plane) Plane = GP;
-    if (!LC.IsIdentity()) {
-      const gp_Trsf& T = LC.Transformation();
-      Handle(Geom_Geometry) GPT = GP->Transformed(T);
-      Plane = Handle(Geom_Plane)::DownCast (GPT);
-    }
-    GeomAdaptor_Surface& GAS = HS->ChangeSurface();
-    GAS.Load(Plane);
-    
-    Handle(Geom_Curve) ProjOnPlane = 
-      GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,f,l),
-                                  Plane,
-                                  Plane->Position().Direction(),
-                                  Standard_True);
-    
-    GeomAdaptor_Curve& GAC = HC->ChangeCurve();
-    GAC.Load(ProjOnPlane);
-
-    ProjLib_ProjectedCurve Proj(HS,HC);
-    Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj);
-
-    if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
-      Handle(Geom2d_TrimmedCurve) TC = 
-        Handle(Geom2d_TrimmedCurve)::DownCast (pc);
-      pc = TC->BasisCurve();
-    }
-    First = f; Last = l;
-    //
-    bToUpdate=Standard_True;
-    //
-    return pc;
-  }
-  
-  return nullPCurve;
-}
-//=======================================================================
 //function : MaxToleranceEdge
 //purpose  : 
 //=======================================================================
index f6f68b5..b84bb1d 100644 (file)
@@ -141,17 +141,6 @@ public:
 
   //! Compute intermediate value of parameter for the edge <anE>.
   Standard_EXPORT static Standard_Real IntermediatePoint (const TopoDS_Edge& anE);
-  
-  //! Build pcurve of edge on face if the surface is plane, and update the edge.
-  Standard_EXPORT static void BuildPCurveForEdgeOnPlane (const TopoDS_Edge& theE, const TopoDS_Face& theF);
-  
-  //! Build pcurve of edge on face if the surface is plane, but do not update the edge.
-  //! The output are the pcurve and the flag telling that pcurve was built.
-  Standard_EXPORT static void BuildPCurveForEdgeOnPlane (const TopoDS_Edge& theE, const TopoDS_Face& theF,
-                                                         Handle(Geom2d_Curve)& aC2D, Standard_Boolean& bToUpdate);
-
-  Standard_EXPORT static void BuildPCurveForEdgesOnPlane (const BOPCol_ListOfShape& theLE, const TopoDS_Face& theF);
-  
 
   //! Make P-Curve <aC> for the edge <aE> on surface <aF> .<br>
   //! [aFirst, aLast] - range of the P-Curve<br>
index 9118d62..9a2e3ed 100644 (file)
@@ -270,19 +270,16 @@ const Handle(Poly_Polygon3D)& BRep_Tool::Polygon3D(const TopoDS_Edge& E,
 Handle(Geom2d_Curve) BRep_Tool::CurveOnSurface(const TopoDS_Edge& E, 
                                                const TopoDS_Face& F,
                                                Standard_Real& First,
-                                               Standard_Real& Last)
+                                               Standard_Real& Last,
+                                               Standard_Boolean* theIsStored)
 {
   TopLoc_Location l;
   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l);
   TopoDS_Edge aLocalEdge = E;
   if (F.Orientation() == TopAbs_REVERSED) {
     aLocalEdge.Reverse();
-//    return CurveOnSurface(E,S,l,First,Last);
   }
-//    return CurveOnSurface(TopoDS::Edge(E.Reversed()),S,l,First,Last);
-//  else
-//    return CurveOnSurface(E,S,l,First,Last);
-  return CurveOnSurface(aLocalEdge,S,l,First,Last);
+  return CurveOnSurface(aLocalEdge, S, l, First, Last, theIsStored);
 }
 
 //=======================================================================
@@ -299,10 +296,13 @@ Handle(Geom2d_Curve) BRep_Tool::CurveOnSurface(const TopoDS_Edge& E,
                                                const Handle(Geom_Surface)& S,
                                                const TopLoc_Location& L,
                                                Standard_Real& First,
-                                               Standard_Real& Last)
+                                               Standard_Real& Last,
+                                               Standard_Boolean* theIsStored)
 {
   TopLoc_Location loc = L.Predivided(E.Location());
   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
+  if (theIsStored)
+    *theIsStored = Standard_True;
 
   // find the representation
   const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
@@ -322,6 +322,8 @@ Handle(Geom2d_Curve) BRep_Tool::CurveOnSurface(const TopoDS_Edge& E,
   }
 
   // Curve is not found. Try projection on plane
+  if (theIsStored)
+    *theIsStored = Standard_False;
   return CurveOnPlane(E, S, L, First, Last);
 }
 
index e81a3ef..ed66f84 100644 (file)
@@ -96,13 +96,28 @@ public:
   //! parametric  space of  the  face.  Returns   a NULL
   //! handle  if this curve  does not exist.  Returns in
   //! <First> and <Last> the parameter range.
-  Standard_EXPORT static Handle(Geom2d_Curve) CurveOnSurface (const TopoDS_Edge& E, const TopoDS_Face& F, Standard_Real& First, Standard_Real& Last);
+  //! If the surface is a plane the curve can be not stored but created a new
+  //! each time. The flag pointed by <theIsStored> serves to indicate storage status. 
+  //! It is valued if the pointer is non-null.
+  Standard_EXPORT static Handle(Geom2d_Curve) CurveOnSurface (const TopoDS_Edge& E,
+                                                              const TopoDS_Face& F,
+                                                              Standard_Real& First,
+                                                              Standard_Real& Last,
+                                                              Standard_Boolean* theIsStored = NULL);
   
   //! Returns the  curve associated to   the edge in the
   //! parametric  space of the   surface. Returns a NULL
   //! handle  if this curve does  not exist.  Returns in
   //! <First> and <Last> the parameter range.
-  Standard_EXPORT static Handle(Geom2d_Curve) CurveOnSurface (const TopoDS_Edge& E, const Handle(Geom_Surface)& S, const TopLoc_Location& L, Standard_Real& First, Standard_Real& Last);
+  //! If the surface is a plane the curve can be not stored but created a new
+  //! each time. The flag pointed by <theIsStored> serves to indicate storage status. 
+  //! It is valued if the pointer is non-null.
+  Standard_EXPORT static Handle(Geom2d_Curve) CurveOnSurface(const TopoDS_Edge& E,
+                                                              const Handle(Geom_Surface)& S,
+                                                              const TopLoc_Location& L,
+                                                              Standard_Real& First,
+                                                              Standard_Real& Last,
+                                                              Standard_Boolean* theIsStored = NULL);
 
   //! For the planar surface builds the 2d curve for the edge
   //! by projection of the edge on plane.
index d19127a..5f034bb 100644 (file)
 #include <Standard_Boolean.hxx>
 #include <GeomAbs_Shape.hxx>
 #include <Standard_Integer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <NCollection_List.hxx>
 
+class Geom2d_Curve;
 class Adaptor3d_Curve;
 class Geom_Plane;
-class TopoDS_Edge;
 class TopoDS_Shape;
 class TopoDS_Solid;
 class TopoDS_Face;
@@ -111,7 +113,26 @@ public:
   //! Computes  the 3d curves  for all the  edges of <S>
   //! return False if one of the computation failed.
   Standard_EXPORT static Standard_Boolean BuildCurves3d (const TopoDS_Shape& S);
-  
+
+  //! Builds pcurve of edge on face if the surface is plane, and updates the edge.
+  Standard_EXPORT static void BuildPCurveForEdgeOnPlane(const TopoDS_Edge& theE, const TopoDS_Face& theF);
+
+  //! Builds pcurve of edge on face if the surface is plane, but does not update the edge.
+  //! The output are the pcurve and the flag telling that pcurve was built.
+  Standard_EXPORT static void BuildPCurveForEdgeOnPlane(const TopoDS_Edge& theE, const TopoDS_Face& theF,
+                                                        Handle(Geom2d_Curve)& aC2D, Standard_Boolean& bToUpdate);
+
+  //! Builds pcurves of edges on face if the surface is plane, and update the edges.
+  template<class TCont> static void BuildPCurveForEdgesOnPlane(const TCont& theLE, const TopoDS_Face& theF)
+  {
+    for (typename TCont::Iterator aIt(theLE); aIt.More(); aIt.Next())
+    {
+      const TopoDS_Edge& aE = TopoDS::Edge(aIt.Value());
+      if (!aE.IsNull())
+        BRepLib::BuildPCurveForEdgeOnPlane(aE, theF);
+    }
+  }
+
   //! Checks if the edge has a  Tolerance smaller than -- --
   //! -- -- MaxToleranceToCheck  if  so it will compute  the
   //! radius    of  -- the   cylindrical  pipe  surface that
index 736ee8e..5366ebf 100644 (file)
@@ -14,6 +14,7 @@
 // commercial license or contractual agreement.
 
 #include <BRepLib.hxx>
+#include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
 #include <BRepAdaptor_Curve.hxx>
 #include <Geom_OffsetCurve.hxx>
@@ -234,3 +235,37 @@ Standard_Boolean BRepLib::FindValidRange
                         aParV[1], aPntV[1], aTolV[1],
                         theFirst, theLast);
 }
+
+//=======================================================================
+//function : BuildPCurveForEdgeOnPlane
+//purpose  : 
+//=======================================================================
+void BRepLib::BuildPCurveForEdgeOnPlane(const TopoDS_Edge& aE,
+                                        const TopoDS_Face& aF)
+{
+  Standard_Boolean bToUpdate;
+  Standard_Real aTolE;
+  Handle(Geom2d_Curve) aC2D;
+  BRep_Builder aBB;
+  //
+  BuildPCurveForEdgeOnPlane(aE, aF, aC2D, bToUpdate);
+  if (bToUpdate) {
+    aTolE = BRep_Tool::Tolerance(aE);
+    aBB.UpdateEdge(aE, aC2D, aF, aTolE);
+  }
+}
+
+//=======================================================================
+//function : BuildPCurveForEdgeOnPlane
+//purpose  : 
+//=======================================================================
+void BRepLib::BuildPCurveForEdgeOnPlane(const TopoDS_Edge& aE,
+                                        const TopoDS_Face& aF,
+                                        Handle(Geom2d_Curve)& aC2D,
+                                        Standard_Boolean& bToUpdate)
+{
+  Standard_Real aT1, aT2;
+  Standard_Boolean isStored;
+  aC2D = BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2, &isStored);
+  bToUpdate = !isStored && !aC2D.IsNull();
+}
index cede6ad..86d84ad 100644 (file)
@@ -30,6 +30,7 @@
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
 
+#include <BRepLib.hxx>
 #include <BRepTools.hxx>
 
 #include <BRepAdaptor_Curve.hxx>
@@ -1365,7 +1366,7 @@ void BuildSplitsOfFace(const TopoDS_Face& theFace,
   aFF.Orientation(TopAbs_FORWARD);
   //
   // build pcurves for edges on the face
-  BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane(aLE, aFF);
+  BRepLib::BuildPCurveForEdgesOnPlane(aLE, aFF);
   //
   // build splits of faces
   BOPAlgo_BuilderFace aBF;
index 5f8e9ce..0ce6b76 100644 (file)
@@ -15,9 +15,6 @@
 
 
 #include <BRep_Builder.hxx>
-#include <BRep_CurveRepresentation.hxx>
-#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
-#include <BRep_TEdge.hxx>
 #include <BRep_Tool.hxx>
 #include <BRepLib.hxx>
 #include <BRepLib_MakeEdge.hxx>
@@ -34,6 +31,7 @@
 #include <Geom_ElementarySurface.hxx>
 #include <Geom_Line.hxx>
 #include <Geom_OffsetSurface.hxx>
+#include <Geom_Plane.hxx>
 #include <Geom_RectangularTrimmedSurface.hxx>
 #include <Geom_Surface.hxx>
 #include <Geom_SurfaceOfLinearExtrusion.hxx>
 #include <ShapeAnalysis_WireOrder.hxx>
 #include <ShapeBuild_Edge.hxx>
 #include <ShapeBuild_ReShape.hxx>
-#include <ShapeExtend_CompositeSurface.hxx>
-#include <ShapeFix_ComposeShell.hxx>
 #include <ShapeFix_Edge.hxx>
 #include <ShapeFix_Face.hxx>
-#include <ShapeFix_SequenceOfWireSegment.hxx>
 #include <ShapeFix_Shell.hxx>
 #include <ShapeFix_Wire.hxx>
-#include <ShapeFix_WireSegment.hxx>
-#include <ShapeUpgrade_RemoveLocations.hxx>
 #include <ShapeUpgrade_UnifySameDomain.hxx>
 #include <Standard_Type.hxx>
 #include <TColGeom2d_Array1OfBSplineCurve.hxx>
@@ -68,7 +61,6 @@
 #include <TColGeom2d_SequenceOfBoundedCurve.hxx>
 #include <TColGeom_Array1OfBSplineCurve.hxx>
 #include <TColGeom_HArray1OfBSplineCurve.hxx>
-#include <TColGeom_HArray2OfSurface.hxx>
 #include <TColGeom_SequenceOfSurface.hxx>
 #include <TColStd_Array1OfReal.hxx>
 #include <TColStd_MapOfInteger.hxx>
@@ -85,7 +77,6 @@
 #include <TopTools_SequenceOfShape.hxx>
 #include <gp_Circ.hxx>
 #include <BRepAdaptor_Curve.hxx>
-#include <BRepClass_FaceClassifier.hxx>
 #include <BRepAdaptor_Curve2d.hxx>
 #include <gp_Vec2d.hxx>
 
@@ -1230,37 +1221,6 @@ void ShapeUpgrade_UnifySameDomain::KeepShapes(const TopTools_MapOfShape& theShap
 }
 
 //=======================================================================
-//function : putIntWires
-//purpose  : Add internal wires that are classified inside the face as a subshape,
-//           and remove them from the sequence
-//=======================================================================
-static void putIntWires(TopoDS_Shape& theFace, TopTools_SequenceOfShape& theWires)
-{
-  TopoDS_Face& aFace = TopoDS::Face(theFace);
-  for (Standard_Integer i=1; i <= theWires.Length(); i++)
-  {
-    TopoDS_Shape aWire = theWires(i);
-    gp_Pnt2d aP2d;
-    Standard_Boolean isP2d = Standard_False;
-    for (TopoDS_Iterator it(aWire); it.More() && !isP2d; it.Next())
-    {
-      const TopoDS_Edge& anEdge = TopoDS::Edge(it.Value());
-      Standard_Real aFirst, aLast;
-      Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, aFace, aFirst, aLast);
-      aC2d->D0((aFirst + aLast) * 0.5, aP2d);
-      isP2d = Standard_True;
-    }
-    BRepClass_FaceClassifier aClass(aFace, aP2d, Precision::PConfusion());
-    if (aClass.State() == TopAbs_IN)
-    {
-      BRep_Builder().Add(aFace, aWire);
-      theWires.Remove(i);
-      i--;
-    }
-  }
-}
-
-//=======================================================================
 //function : UnifyFaces
 //purpose  : 
 //=======================================================================
@@ -1291,6 +1251,24 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces()
 }
 
 //=======================================================================
+//function : SetFixWireModes
+//purpose  : 
+//=======================================================================
+
+static void SetFixWireModes(ShapeFix_Face& theSff)
+{
+  Handle(ShapeFix_Wire) aFixWire = theSff.FixWireTool();
+  aFixWire->FixSelfIntersectionMode() = 0;
+  aFixWire->FixNonAdjacentIntersectingEdgesMode() = 0;
+  aFixWire->FixLackingMode() = 0;
+  aFixWire->FixNotchedEdgesMode() = 0;
+  aFixWire->ModifyTopologyMode() = Standard_False;
+  aFixWire->ModifyRemoveLoopMode() = 0;
+  aFixWire->FixGapsByRangesMode() = Standard_False;
+  aFixWire->FixSmallMode() = 0;
+}
+
+//=======================================================================
 //function : IntUnifyFaces
 //purpose  : 
 //=======================================================================
@@ -1306,10 +1284,6 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
   // map of processed shapes
   TopTools_MapOfShape aProcessed;
 
-  // Check status of the unification
-  Standard_Integer NbModif = 0;
-  Standard_Boolean hasFailed = Standard_False;
-
   // processing each face
   TopExp_Explorer exp;
   for (exp.Init(theInpShape, TopAbs_FACE); exp.More(); exp.Next()) {
@@ -1356,6 +1330,11 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
         continue;
       }
 
+      // for a planar face create and store pcurve of edge on face
+      // to speed up all operations
+      if (!mySafeInputMode && aBaseSurface->IsKind(STANDARD_TYPE(Geom_Plane)))
+        BRepLib::BuildPCurveForEdgeOnPlane(edge, aFace);
+
       // get normal of the face to compare it with normals of other faces
       gp_Dir aDN1;
       //
@@ -1416,8 +1395,6 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
       for (i = 1; i <= faces.Length(); i++) {
         TopExp::MapShapesAndAncestors(faces(i), TopAbs_EDGE, TopAbs_FACE, aMapEF);
       }
-      if (mySafeInputMode)
-        UpdateMapOfShapes(myKeepShapes, myContext);
       // Collect keep edges and multi-connected edges, i.e. edges that are internal to
       // the set of selected faces and have connections to other faces.
       TopTools_ListOfShape aKeepEdges;
@@ -1506,13 +1483,12 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
 
     // all faces collected in the sequence. Perform union of faces
     if (faces.Length() > 1) {
-      NbModif++;
       TopoDS_Face aResult;
       BRep_Builder B;
       B.MakeFace(aResult,aBaseSurface,aBaseLocation,0);
       Standard_Integer nbWires = 0;
 
-      TopoDS_Face tmpF = TopoDS::Face(myContext->Apply(faces(1).Oriented(TopAbs_FORWARD)));
+      TopoDS_Face tmpF = TopoDS::Face(faces(1).Oriented(TopAbs_FORWARD));
 
       // connecting wires
       while (edges.Length()>0) {
@@ -1559,12 +1535,10 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
 
         // sorting any type of edges
         aWire.Closed (BRep_Tool::IsClosed (aWire));
-        aWire = TopoDS::Wire(myContext->Apply(aWire));
 
         Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire(aWire,tmpF,Precision::Confusion());
         if (mySafeInputMode)
           sfw->SetContext(myContext);
-        sfw->FixEdgeCurves();
         sfw->FixReorder();
         Standard_Boolean isDegRemoved = Standard_False;
         if(!sfw->StatusReorder ( ShapeExtend_FAIL )) {
@@ -1584,12 +1558,11 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
           if(isDegRemoved)
             sfw->FixDegenerated();
         }
-        TopoDS_Wire aWireFixed = sfw->Wire();
-        myContext->Replace(aWire,aWireFixed);
+        aWire = sfw->Wire();
 
         // add resulting wire
         if(isEdge3d) {
-          B.Add(aResult,aWireFixed);
+          B.Add(aResult,aWire);
         }
         else  {
           // sorting edges
@@ -1639,99 +1612,25 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
         }
       }
 
-      // perform substitution of face
-      myContext->Replace(myContext->Apply(aFace),aResult);
-
       ShapeFix_Face sff (aResult);
       //Initializing by tolerances
       sff.SetPrecision(Precision::Confusion());
       sff.SetMinTolerance(Precision::Confusion());
       sff.SetMaxTolerance(1.);
       //Setting modes
-      sff.FixOrientationMode() = 0;
-      //sff.FixWireMode() = 0;
-      sff.SetContext(myContext);
+      SetFixWireModes(sff);
+      if (mySafeInputMode)
+        sff.SetContext(myContext);
       // Applying the fixes
       sff.Perform();
-      if(sff.Status(ShapeExtend_FAIL))
-        hasFailed = Standard_True;
-
-      // breaking down to several faces
-      TopoDS_Shape theResult = myContext->Apply(aResult);
-      for (TopExp_Explorer aFaceExp (theResult,TopAbs_FACE); aFaceExp.More(); aFaceExp.Next()) {
-        TopoDS_Face aCurrent = TopoDS::Face(aFaceExp.Current().Oriented(TopAbs_FORWARD));
-        Handle(TColGeom_HArray2OfSurface) grid = new TColGeom_HArray2OfSurface ( 1, 1, 1, 1 );
-        grid->SetValue ( 1, 1, aBaseSurface );
-        Handle(ShapeExtend_CompositeSurface) G = new ShapeExtend_CompositeSurface ( grid );
-        ShapeFix_ComposeShell CompShell;
-        CompShell.Init ( G, aBaseLocation, aCurrent, ::Precision::Confusion() );//myPrecision
-        CompShell.SetContext( myContext );
-
-        TopTools_SequenceOfShape parts, anIntWires;
-        ShapeFix_SequenceOfWireSegment wires;
-        for(TopExp_Explorer W_Exp(aCurrent,TopAbs_WIRE);W_Exp.More();W_Exp.Next()) {
-          const TopoDS_Wire& aWire = TopoDS::Wire(W_Exp.Current());
-          // check if the wire is ordinary (contains non-internal edges)
-          Standard_Boolean isInternal = Standard_True;
-          for (TopoDS_Iterator it(aWire); it.More() && isInternal; it.Next())
-            isInternal = (it.Value().Orientation() == TopAbs_INTERNAL);
-          if (isInternal)
-          {
-            // place internal wire separately
-            anIntWires.Append(aWire);
-          }
-          else
-          {
-            Handle(ShapeExtend_WireData) sbwd =
-              new ShapeExtend_WireData (aWire);
-            ShapeFix_WireSegment seg ( sbwd, TopAbs_REVERSED );
-            wires.Append(seg);
-          }
-        }
-
-        CompShell.DispatchWires( parts, wires );
-        for (Standard_Integer j=1; j <= parts.Length(); j++ ) {
-          ShapeFix_Face aFixOrient(TopoDS::Face(parts(j)));
-          aFixOrient.SetContext(myContext);
-          aFixOrient.FixOrientation();
-          // put internal wires to faces
-          putIntWires(parts(j), anIntWires);
-        }
-
-        TopoDS_Shape CompRes;
-        if ( parts.Length() !=1 ) {
-          TopoDS_Shell S;
-          B.MakeShell ( S );
-          for ( i=1; i <= parts.Length(); i++ )
-            B.Add ( S, parts(i) );
-          S.Closed (BRep_Tool::IsClosed (S));
-          CompRes = S;
-        }
-        else CompRes = parts(1);
-
-        myContext->Replace(aCurrent,CompRes);
+      if(!sff.Status(ShapeExtend_FAIL))
+      {
+        // perform substitution of faces
+        aResult = sff.Face();
+        myContext->Merge(faces, aResult);
       }
-
-      const TopoDS_Shape aResult3 = myContext->Apply(theResult);
-      myContext->Merge(faces, aResult3);
     }
   } // end processing each face
-
-  //TopoDS_Shape aResult = Shape;
-  if (NbModif > 0 && !hasFailed) {
-    TopoDS_Shape aResult = myContext->Apply(theInpShape);
-
-    ShapeFix_Edge sfe;
-    if (!myContext.IsNull()) sfe.SetContext(myContext);
-    for (exp.Init(aResult,TopAbs_EDGE); exp.More(); exp.Next()) {
-      TopoDS_Edge E = TopoDS::Edge(exp.Current());
-      sfe.FixVertexTolerance (E);
-      // ptv add fix same parameter
-      sfe.FixSameParameter(E, Precision::Confusion());
-    }
-
-    myContext->Replace(theInpShape, aResult);
-  }
 }
 
 //=======================================================================
@@ -1859,13 +1758,38 @@ void ShapeUpgrade_UnifySameDomain::UnifyEdges()
     TopoDS_Face aFace = TopoDS::Face(myContext->Apply(ChangedFaces.FindKey(i)));
     if (aFace.IsNull())
       continue;
-    Handle(ShapeFix_Face) sff = new ShapeFix_Face(aFace);
-    sff->SetContext(myContext);
-    sff->SetPrecision(aPrec);
-    sff->SetMinTolerance(aPrec);
-    sff->SetMaxTolerance(Max(1., aPrec*1000.));
-    sff->Perform();
-    TopoDS_Shape aNewFace = sff->Face();
+
+    // for a planar face create and store pcurve of edge on face
+    // to speed up all operations; but this is allowed only when non-safe mode in force
+    if (!mySafeInputMode)
+    {
+      TopLoc_Location aLoc;
+      Handle(Geom_Surface) aSurface = BRep_Tool::Surface(aFace, aLoc);
+      aSurface = ClearRts(aSurface);
+      if (aSurface->IsKind(STANDARD_TYPE(Geom_Plane)))
+      {
+        TopTools_ListOfShape aLE;
+        for (TopExp_Explorer anEx(aFace, TopAbs_EDGE); anEx.More(); anEx.Next())
+          aLE.Append(anEx.Current());
+        BRepLib::BuildPCurveForEdgesOnPlane(aLE, aFace);
+      }
+    }
+
+    ShapeFix_Face sff(aFace);
+    if (mySafeInputMode)
+      sff.SetContext(myContext);
+    sff.SetPrecision(aPrec);
+    sff.SetMinTolerance(aPrec);
+    sff.SetMaxTolerance(Max(1., aPrec*1000.));
+    sff.FixOrientationMode() = 0;
+    sff.FixAddNaturalBoundMode() = 0;
+    sff.FixIntersectingWiresMode() = 0;
+    sff.FixLoopWiresMode() = 0;
+    sff.FixSplitFaceMode() = 0;
+    sff.FixPeriodicDegeneratedMode() = 0;
+    SetFixWireModes(sff);
+    sff.Perform();
+    TopoDS_Shape aNewFace = sff.Face();
     myContext->Replace(aFace,aNewFace);
   }
 
@@ -1893,36 +1817,15 @@ void ShapeUpgrade_UnifySameDomain::UnifyEdges()
 }
 
 //=======================================================================
-//function : UnifyFacesAndEdges
-//purpose  : 
-//=======================================================================
-
-void ShapeUpgrade_UnifySameDomain::UnifyFacesAndEdges()
-{
-  UnifyFaces();
-  
-  /*
-  ShapeUpgrade_RemoveLocations RemLoc;
-  RemLoc.Remove(myShape);
-  myShape = RemLoc.GetResult();
-  */
-
-  UnifyEdges();
-}
-
-//=======================================================================
 //function : Build
 //purpose  : builds the resulting shape
 //=======================================================================
 void ShapeUpgrade_UnifySameDomain::Build() 
 {
-  if (myUnifyFaces && myUnifyEdges)
-    UnifyFacesAndEdges();
-
-  else if (myUnifyEdges)
-    UnifyEdges();
-  else if (myUnifyFaces)
+  if (myUnifyFaces)
     UnifyFaces();
+  if (myUnifyEdges)
+    UnifyEdges();
 
   // Fill the history of modifications during the operation
   FillHistory();
index 618aadb..13f8c95 100644 (file)
@@ -107,17 +107,6 @@ public:
   {
     return myShape;
   }
-  
-  //! this method makes if possible a common face from each
-  //! group of faces lying on coincident surfaces
-  Standard_EXPORT void UnifyFaces();
-  
-  //! this method makes if possible a common edge from each
-  //! group of edges connecting common couple of faces
-  Standard_EXPORT void UnifyEdges();
-  
-  //! this method unifies same domain faces and edges
-  Standard_EXPORT void UnifyFacesAndEdges();
 
   //! Returns the history of the processed shapes.
   const Handle(BRepTools_History)& History() const
@@ -135,10 +124,13 @@ public:
 
 protected:
 
+  //! this method makes if possible a common face from each
+  //! group of faces lying on coincident surfaces
+  Standard_EXPORT void UnifyFaces();
 
-
-
-private:
+  //! this method makes if possible a common edge from each
+  //! group of edges connecting common couple of faces
+  Standard_EXPORT void UnifyEdges();
 
   void IntUnifyFaces(const TopoDS_Shape& theInpShape,
                      TopTools_IndexedDataMapOfShapeListOfShape& theGMapEdgeFaces,
@@ -147,6 +139,7 @@ private:
   //! Fills the history of the modifications during the operation.
   Standard_EXPORT void FillHistory();
 
+private:
 
   TopoDS_Shape myInitShape;
   Standard_Real myLinTol;
index 4bb28c4..e338a1e 100644 (file)
@@ -32,7 +32,7 @@ if {$bug_info != ""} {
 
 set bug_info [unifysamedommod res a_3]
 set bug_info [string trim [string range $bug_info 0 [expr {[string first "\n" $bug_info] - 1}]]]
-if {$bug_info != ""} {
+if {$bug_info != "The shape has not been modified"} {
   puts "ERROR: OCC28226 is reproduced. Command unifysamedommod does not work correctly."
 }
 
index 4f9e005..61e9b73 100644 (file)
@@ -13,7 +13,7 @@ brestore [locate_data_file bug28913_26219_model.brep] a
 unifysamedom result a
 
 checkshape result
-checknbshapes result -vertex 76 -edge 125 -wire 51 -face 44
+checknbshapes result -vertex 76 -edge 124 -wire 51 -face 44
 checkprops result -s 1473.4
 
 checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
diff --git a/tests/perf/heal/bug28467_1 b/tests/perf/heal/bug28467_1
new file mode 100644 (file)
index 0000000..d4c61b8
--- /dev/null
@@ -0,0 +1,23 @@
+puts "======="
+puts "0028467"
+puts "======="
+puts ""
+##################################################
+# Improve UnifySameDomain performance
+##################################################
+
+autodisplay 0
+
+restore [locate_data_file bug28467_shape1.brep] a
+
+removeloc a a
+
+chrono h reset;chrono h start
+unifysamedom r a -nosafe
+chrono h stop
+
+checknbshapes r -m "unifysamedom result" -vertex 2236 -edge 3504 -wire 1238 -face 1175
+checkprops r -s 2.23714e+006 -l 242654
+checkshape r
+
+chrono h show COUNTER unifysamedom
diff --git a/tests/perf/heal/bug28467_2 b/tests/perf/heal/bug28467_2
new file mode 100644 (file)
index 0000000..6a5b4f0
--- /dev/null
@@ -0,0 +1,23 @@
+puts "======="
+puts "0028467"
+puts "======="
+puts ""
+##################################################
+# Improve UnifySameDomain performance
+##################################################
+
+autodisplay 0
+
+restore [locate_data_file bug28467_shape2.brep] a
+
+removeloc a a
+
+chrono h reset;chrono h start
+unifysamedom r a -nosafe
+chrono h stop
+
+checknbshapes r -m "unifysamedom result" -vertex 1008 -edge 1512 -wire 656 -face 581
+checkprops r -s 3.9225e+006 -l 181240
+checkshape r
+
+chrono h show COUNTER unifysamedom
diff --git a/tests/perf/heal/bug28467_3 b/tests/perf/heal/bug28467_3
new file mode 100644 (file)
index 0000000..79474f0
--- /dev/null
@@ -0,0 +1,23 @@
+puts "======="
+puts "0028467"
+puts "======="
+puts ""
+##################################################
+# Improve UnifySameDomain performance
+##################################################
+
+autodisplay 0
+
+restore [locate_data_file bug28467_r_unif.brep] a
+
+removeloc a a
+
+chrono h reset;chrono h start
+unifysamedom r a -nosafe
+chrono h stop
+
+checknbshapes r -m "unifysamedom result" -vertex 1176 -edge 1764 -wire 590 -face 590
+checkprops r -s 3.4136e+006 -l 193520
+checkshape r
+
+chrono h show COUNTER unifysamedom