]> OCCT Git - occt.git/commitdiff
0032213: Modeling Algorithms - Invalid result of UnifySameDomain
authorjgv <jgv@opencascade.com>
Thu, 8 Apr 2021 00:49:14 +0000 (03:49 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 16 Apr 2021 15:27:34 +0000 (18:27 +0300)
Modify unification of faces: add splitting new wire into several ones.

src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx
tests/bugs/heal/bug32213 [new file with mode: 0644]
tests/bugs/modalg_7/bug32189 [new file with mode: 0644]

index 3ad5f0b900411784cb2c710671d7f7f4005920dc..cec3dbd159bd1ad75499ddfd0b05809522b94c61 100644 (file)
 
 IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_UnifySameDomain,Standard_Transient)
 
+static void SplitWire (const TopoDS_Wire&                theWire,
+                       const TopoDS_Face&                theFace,
+                       const TopTools_IndexedMapOfShape& theVmap,
+                       TopTools_SequenceOfShape&         theWireSeq);
+
 static Standard_Real TrueValueOfOffset(const Standard_Real theValue,
                                        const Standard_Real thePeriod)
 {
@@ -3012,6 +3017,7 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
         BB.MakeWire(aNewWire);
         BB.Add(aNewWire, StartEdge);
         RemoveEdgeFromMap(StartEdge, VEmap);
+        TopTools_IndexedMapOfShape SplittingVertices;
         
         Standard_Real fpar, lpar;
         Handle(Geom2d_Curve) StartPCurve = BRep_Tool::CurveOnSurface(StartEdge, F_RefFace, fpar, lpar);
@@ -3093,6 +3099,7 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
             else
             {
               //we must choose the closest direction - the biggest angle
+              SplittingVertices.Add (CurVertex);
               Standard_Real MaxAngle = RealFirst();
               TopoDS_Edge TrueEdge;
               Handle(Geom2d_Curve) CurPCurve = BRep_Tool::CurveOnSurface(CurEdge, F_RefFace, fpar, lpar);
@@ -3242,7 +3249,11 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
         }
         else //may be this wire is a hole
         {
-          NewWires.Append(aNewWire);
+          //split this wire if needed
+          if (!SplittingVertices.IsEmpty())
+            SplitWire (aNewWire, F_RefFace, SplittingVertices, NewWires);
+          else
+            NewWires.Append(aNewWire);
         }
       } //while (!edges.IsEmpty())
 
@@ -3575,3 +3586,112 @@ void ShapeUpgrade_UnifySameDomain::FillHistory()
   // Merge the history of the operation into global history
   myHistory->Merge(aUSDHistory);
 }
+
+void SplitWire (const TopoDS_Wire&                theWire,
+                const TopoDS_Face&                theFace,
+                const TopTools_IndexedMapOfShape& theVmap,
+                TopTools_SequenceOfShape&         theWireSeq)
+{
+  TopTools_DataMapOfShapeListOfShape aVEmap;
+
+  TopTools_MapOfShape aEmap;
+  TopoDS_Iterator itw (theWire);
+  for (; itw.More(); itw.Next())
+  {
+    const TopoDS_Edge& anEdge = TopoDS::Edge (itw.Value());
+    if (!aEmap.Add (anEdge))
+      continue;
+    if (anEdge.Orientation() != TopAbs_FORWARD &&
+        anEdge.Orientation() != TopAbs_REVERSED)
+      continue;
+
+    const TopoDS_Vertex& aVertex = TopExp::FirstVertex (anEdge, Standard_True); //with orientation
+    if (aVEmap.IsBound (aVertex))
+      aVEmap(aVertex).Append (anEdge);
+    else
+    {
+      TopTools_ListOfShape aElist;
+      aElist.Append (anEdge);
+      aVEmap.Bind (aVertex, aElist);
+    }
+  }
+
+  BRep_Builder aBB;
+  for (Standard_Integer ii = 1; ii <= theVmap.Extent(); ii++)
+  {
+    const TopoDS_Vertex& anOrigin = TopoDS::Vertex (theVmap(ii));
+    TopTools_ListOfShape& aBranches = aVEmap (anOrigin);
+    TopTools_ListIteratorOfListOfShape anItl (aBranches);
+    while (anItl.More())
+    {
+      TopoDS_Edge CurEdge = TopoDS::Edge (anItl.Value());
+      aBranches.Remove (anItl);
+      
+      TopoDS_Wire aNewWire;
+      aBB.MakeWire (aNewWire);
+      for (;;)
+      {
+        aBB.Add (aNewWire, CurEdge);
+        
+        const TopoDS_Vertex& aVertex = TopExp::LastVertex (CurEdge, Standard_True); //with orientation
+        if (aVertex.IsSame(anOrigin))
+          break;
+
+        if (!aVEmap.IsBound (aVertex))
+          break;
+
+        TopTools_ListOfShape& aElist = aVEmap (aVertex);
+        if (aElist.Extent() == 0)
+          break;
+        
+        if (aElist.Extent() == 1)
+        {
+          CurEdge = TopoDS::Edge (aElist.First());
+          aElist.Clear();
+        }
+        else
+        {
+          Standard_Real fpar, lpar;
+          Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(CurEdge, theFace, fpar, lpar);
+          Standard_Real aParam = (CurEdge.Orientation() == TopAbs_FORWARD)? lpar : fpar;
+          gp_Pnt2d aPoint;
+          gp_Vec2d CurDir;
+          aPCurve->D1(aParam, aPoint, CurDir);
+          CurDir.Normalize();
+          if (CurEdge.Orientation() == TopAbs_REVERSED)
+            CurDir.Reverse();
+          //choose the rightest direction - the smallest angle
+          Standard_Real MinAngle = RealLast();
+          TopoDS_Edge NextEdge;
+          TopTools_ListIteratorOfListOfShape aLocalIter (aElist);
+          for (; aLocalIter.More(); aLocalIter.Next())
+          {
+            const TopoDS_Edge& anEdge = TopoDS::Edge(aLocalIter.Value());
+            aPCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, fpar, lpar);
+            aParam = (anEdge.Orientation() == TopAbs_FORWARD)? fpar : lpar;
+            gp_Vec2d aDir;
+            aPCurve->D1(aParam, aPoint, aDir);
+            aDir.Normalize();
+            if (anEdge.Orientation() == TopAbs_REVERSED)
+              aDir.Reverse();
+            Standard_Real anAngle = CurDir.Angle(aDir);
+            if (anAngle < MinAngle)
+            {
+              MinAngle = anAngle;
+              NextEdge = anEdge;
+            }
+          }
+          CurEdge = NextEdge;
+          //Remove <CurEdge> from list
+          for (aLocalIter.Initialize(aElist); aLocalIter.More(); aLocalIter.Next())
+            if (CurEdge.IsSame (aLocalIter.Value()))
+            {
+              aElist.Remove (aLocalIter);
+              break;
+            }
+        } //else (more than one edge)
+      } //for (;;)
+      theWireSeq.Append (aNewWire);
+    } //while (anItl.More())
+  }
+}
diff --git a/tests/bugs/heal/bug32213 b/tests/bugs/heal/bug32213
new file mode 100644 (file)
index 0000000..36109b7
--- /dev/null
@@ -0,0 +1,20 @@
+puts "==========================================="
+puts "OCC32213: Invalid result of UnifySameDomain"
+puts "==========================================="
+puts ""
+
+restore [locate_data_file bug32213.brep] a
+
+unifysamedom result a
+
+checkshape result
+
+checknbshapes result -solid 1 -shell 1 -face 21 -wire 22 -edge 58 -vertex 38
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 6.e-6} {
+   puts "Error: bad tolerance of result"
+}
+
+checkprops result -s 81.9221
\ No newline at end of file
diff --git a/tests/bugs/modalg_7/bug32189 b/tests/bugs/modalg_7/bug32189
new file mode 100644 (file)
index 0000000..c79eaac
--- /dev/null
@@ -0,0 +1,15 @@
+puts "============================="
+puts " 0032189: BOP Cut regression"
+puts "============================="
+puts ""
+
+restore [locate_data_file bug32189_a.brep] a
+restore [locate_data_file bug32189_b.brep] b
+
+bcut result a b
+
+checkshape result
+checknbshapes result -vertex 5 -edge 6 -wire 3 -face 3 -shell 1 -solid 1
+checkprops result -s 0.000687454 -v 8.86946e-07
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file