From 84f42008b74b4545e18e0ec361fd14e48d6a961d Mon Sep 17 00:00:00 2001
From: abulyche <abulyche@opencascade.com>
Date: Sun, 17 Apr 2022 17:07:01 +0300
Subject: [PATCH] 0027081:  BRepOffsetAPI_MakeOffsetShape fails on shapes with
 internal edges Added the test for this problem. Added new draw command
 "mkoffsetshape".

---
 src/BRepTest/BRepTest_FeatureCommands.cxx | 80 +++++++++++++++++++++++
 tests/offset/bugs/bug27081                |  9 +++
 2 files changed, 89 insertions(+)
 create mode 100644 tests/offset/bugs/bug27081

diff --git a/src/BRepTest/BRepTest_FeatureCommands.cxx b/src/BRepTest/BRepTest_FeatureCommands.cxx
index 8b69ec1ba2..7b6a829dbc 100644
--- a/src/BRepTest/BRepTest_FeatureCommands.cxx
+++ b/src/BRepTest/BRepTest_FeatureCommands.cxx
@@ -42,6 +42,7 @@
 #include <LocOpe_FindEdgesInFace.hxx>
 
 #include <BRepOffset_MakeOffset.hxx>
+#include <BRepOffsetAPI_MakeOffsetShape.hxx>
 #include <BRepOffset_MakeSimpleOffset.hxx>
 #include <BRep_Builder.hxx>
 #include <DBRep.hxx>
@@ -976,6 +977,81 @@ Standard_Integer thickshell(Draw_Interpretor& theCommands,
   return 0;
 }
 
+//=======================================================================
+//function : mkoffsetshape
+//purpose :
+//=======================================================================
+static Standard_Integer mkoffsetshape(Draw_Interpretor& theDI,
+  Standard_Integer  theArgNb,
+  const char**      theArgVec)
+{
+  if (theArgNb < 4)
+  {
+    return 0;
+  }
+  TopoDS_Shape aShape = DBRep::Get(theArgVec[2]);
+  if (aShape.IsNull())
+  {
+    theDI << "Shape is null";
+    return 1;
+  }
+  Standard_Real anOffVal = Draw::Atof(theArgVec[3]);
+  BRepOffsetAPI_MakeOffsetShape aMaker;
+  if (theArgNb == 4)
+  {
+    aMaker.PerformBySimple(aShape, anOffVal);
+  }
+  else
+  {
+    Standard_Real aTol = Draw::Atof(theArgVec[4]);
+
+    Standard_Boolean anInt = Standard_False;
+    if (theArgNb > 5)
+    {
+      if ((Draw::Atof(theArgVec[5]) == 1))
+      {
+        anInt = Standard_True;
+      }
+    }
+
+    Standard_Boolean aSelfInt = Standard_False;
+    if (theArgNb > 6)
+    {
+      if (Draw::Atof(theArgVec[6]) == 1)
+      {
+        aSelfInt = Standard_True;
+      }
+    }
+
+    GeomAbs_JoinType aJoin = GeomAbs_Arc;
+    if (theArgNb > 7)
+    {
+      if (!strcmp(theArgVec[7], "i"))
+      {
+        aJoin = GeomAbs_Intersection;
+      }
+    }
+
+    Standard_Boolean aRemIntEdges = Standard_False;
+    if (theArgNb > 8)
+    {
+      if (Draw::Atof(theArgVec[8]) == 1)
+      {
+        aRemIntEdges = Standard_True;
+      }
+    }
+    aMaker.PerformByJoin(aShape, anOffVal, aTol, BRepOffset_Skin, anInt, aSelfInt, aJoin, aRemIntEdges);
+  }
+  
+  if (!aMaker.IsDone())
+  {
+    theDI << " Error: Offset is not done.\n";
+    return 1;
+  }
+  DBRep::Set(theArgVec[1], aMaker.Shape());
+  return 0;
+}
+
 //=======================================================================
 //function : offsetshape
 //purpose  : 
@@ -2477,6 +2553,10 @@ void BRepTest::FeatureCommands(Draw_Interpretor& theCommands)
     "thickshell r shape offset [jointype [tol] ]",
     __FILE__, thickshell, g);
 
+  theCommands.Add("mkoffsetshape",
+    "mkoffsetshape r shape offset [Tol] [Intersection(0/1)] [SelfInter(0/1)] [JoinType(a/i)] [RemoveInternalEdges(0/1)]",
+    __FILE__, mkoffsetshape, g);
+
   theCommands.Add("offsetshape",
     "offsetshape r shape offset [tol] [face ...]",
     __FILE__, offsetshape, g);
diff --git a/tests/offset/bugs/bug27081 b/tests/offset/bugs/bug27081
new file mode 100644
index 0000000000..9d69162749
--- /dev/null
+++ b/tests/offset/bugs/bug27081
@@ -0,0 +1,9 @@
+puts "================================================================="
+puts "OCC27081: Modeling Algorithms - BRepOffsetAPI_MakeOffsetShape fails on shapes with internal edges"
+puts "================================================================="
+puts ""
+
+restore [locate_data_file bug27081.brep] sh
+
+mkoffsetshape result sh 1 1e-7 1 0 i
+checkshape result