0023394: Problem with BRepOffset_MakeOffset on a cylindrical face
authoremv <emv@opencascade.com>
Thu, 27 Sep 2012 08:29:04 +0000 (12:29 +0400)
committeremv <emv@opencascade.com>
Thu, 27 Sep 2012 08:29:04 +0000 (12:29 +0400)
src/BRepOffset/BRepOffset_MakeOffset.cxx
tests/bugs/modalg/CR23394 [new file with mode: 0755]

index 05e2f7f..7e452f4 100755 (executable)
 #include <Adaptor3d_CurveOnSurface.hxx>
 #include <GeomLib.hxx>
 #include <GeomFill_Generator.hxx>
+#include <Geom_Plane.hxx>
+#include <IntTools_FClass2d.hxx>
+#include <BRepLib_FindSurface.hxx>
 
 
 // POP for NT
@@ -2860,9 +2863,55 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
             gp_Dir CircAxisDir = aCirc.Axis().Direction();
             if (aCirc.Axis().IsParallel(aCircOE.Axis(), Precision::Confusion()) &&
                 anAxisLine.Contains(aCircOE.Location(), Precision::Confusion()))
-            { //cylinder or cone
+            { //cylinder, plane or cone
               if (Abs(aCirc.Radius() - aCircOE.Radius()) <= Precision::Confusion()) //case of cylinder
                 theSurf = GC_MakeCylindricalSurface(aCirc).Value();
+              else if (aCirc.Location().Distance(aCircOE.Location()) <= Precision::Confusion()) {//case of plane
+                IsPlanar = Standard_True;
+                //
+                gp_Pnt PonEL = BAcurve.Value(lpar);
+                if (PonEL.Distance(PonE) <= Precision::PConfusion()) {
+                  Standard_Boolean bIsHole;
+                  TopoDS_Edge aE1, aE2;
+                  TopoDS_Wire aW1, aW2;
+                  Handle(Geom_Plane) aPL;
+                  IntTools_FClass2d aClsf;
+                  //
+                  if (aCirc.Radius()>aCircOE.Radius()) {
+                    aE1 = anEdge;
+                    aE2 = OE;
+                  } else {
+                    aE1 = OE;
+                    aE2 = anEdge;
+                  }
+                  //
+                  BB.MakeWire(aW1);
+                  BB.Add(aW1, aE1);
+                  BB.MakeWire(aW2);
+                  BB.Add(aW2, aE2);
+                  //
+                  aPL = new Geom_Plane(aCirc.Location(), CircAxisDir);
+                  for (Standard_Integer i = 0; i < 2; ++i) {
+                    TopoDS_Wire& aW = (i==0) ? aW1 : aW2;
+                    TopoDS_Edge& aE = (i==0) ? aE1 : aE2;
+                    //
+                    TopoDS_Face aFace;
+                    BB.MakeFace(aFace, aPL, Precision::Confusion());
+                    BB.Add (aFace, aW);
+                    aClsf.Init(aFace, Precision::Confusion());
+                    bIsHole=aClsf.IsHole();
+                    if ((bIsHole && !i) || (!bIsHole && i)) {
+                      aW.Nullify();
+                      BB.MakeWire(aW);
+                      BB.Add(aW, aE.Reversed());
+                    }
+                  }
+                  //
+                  BB.MakeFace(NewFace, aPL, Precision::Confusion());
+                  BB.Add(NewFace, aW1);
+                  BB.Add(NewFace, aW2);
+                }
+              }
               else //case of cone
               {
                 gp_Cone theCone = gce_MakeCone(aCirc.Location(), aCircOE.Location(),
@@ -2876,42 +2925,44 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
                 theCone.SetPosition(theAx3);
                 theSurf = new Geom_ConicalSurface(theCone);
               }
-              TopLoc_Location Loc;
-              EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., 0.), gp_Dir2d(1., 0.));
-              BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
-              Standard_Real Coeff = (OffsetDir * CircAxisDir > 0.)? 1. : -1.;
-              OELine2d = new Geom2d_Line(gp_Pnt2d(0., OffsetVal*Coeff), gp_Dir2d(1., 0.));
-              BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
-              aLine2d  = new Geom2d_Line(gp_Pnt2d(ParV2, 0.), gp_Dir2d(0., Coeff));
-              aLine2d2 = new Geom2d_Line(gp_Pnt2d(ParV1, 0.), gp_Dir2d(0., Coeff));
-              if (E3.IsSame(E4))
-              {
-                if (Coeff > 0.)
-                  BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
+              if (!IsPlanar) {
+                TopLoc_Location Loc;
+                EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., 0.), gp_Dir2d(1., 0.));
+                BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
+                Standard_Real Coeff = (OffsetDir * CircAxisDir > 0.)? 1. : -1.;
+                OELine2d = new Geom2d_Line(gp_Pnt2d(0., OffsetVal*Coeff), gp_Dir2d(1., 0.));
+                BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
+                aLine2d  = new Geom2d_Line(gp_Pnt2d(ParV2, 0.), gp_Dir2d(0., Coeff));
+                aLine2d2 = new Geom2d_Line(gp_Pnt2d(ParV1, 0.), gp_Dir2d(0., Coeff));
+                if (E3.IsSame(E4))
+                {
+                  if (Coeff > 0.)
+                    BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
+                  else
+                  {
+                    BB.UpdateEdge(E3, aLine2d2, aLine2d, theSurf, Loc, Precision::Confusion());
+                    theWire.Nullify();
+                    BB.MakeWire(theWire);
+                    BB.Add(theWire, anEdge.Oriented(TopAbs_REVERSED));
+                    BB.Add(theWire, E4);
+                    BB.Add(theWire, OE.Oriented(TopAbs_FORWARD));
+                    BB.Add(theWire, E3);
+                    theWire.Closed(Standard_True);
+                  }
+                }
                 else
                 {
-                  BB.UpdateEdge(E3, aLine2d2, aLine2d, theSurf, Loc, Precision::Confusion());
-                  theWire.Nullify();
-                  BB.MakeWire(theWire);
-                  BB.Add(theWire, anEdge.Oriented(TopAbs_REVERSED));
-                  BB.Add(theWire, E4);
-                  BB.Add(theWire, OE.Oriented(TopAbs_FORWARD));
-                  BB.Add(theWire, E3);
-                  theWire.Closed(Standard_True);
+                  BB.SameParameter(E3, Standard_False);
+                  BB.SameRange(E3, Standard_False);
+                  BB.SameParameter(E4, Standard_False);
+                  BB.SameRange(E4, Standard_False);
+                  BB.UpdateEdge(E3, aLine2d,  theSurf, Loc, Precision::Confusion());
+                  BB.Range(E3, theSurf, Loc, 0., OffsetVal);
+                  BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
+                  BB.Range(E4, theSurf, Loc, 0., OffsetVal);
                 }
+                NewFace = BRepLib_MakeFace(theSurf, theWire);
               }
-              else
-              {
-                BB.SameParameter(E3, Standard_False);
-                BB.SameRange(E3, Standard_False);
-                BB.SameParameter(E4, Standard_False);
-                BB.SameRange(E4, Standard_False);
-                BB.UpdateEdge(E3, aLine2d,  theSurf, Loc, Precision::Confusion());
-                BB.Range(E3, theSurf, Loc, 0., OffsetVal);
-                BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
-                BB.Range(E4, theSurf, Loc, 0., OffsetVal);
-              }
-              NewFace = BRepLib_MakeFace(theSurf, theWire);
             } //cylinder or cone
           } //if both edges are arcs of circles
          if (NewFace.IsNull())
diff --git a/tests/bugs/modalg/CR23394 b/tests/bugs/modalg/CR23394
new file mode 100755 (executable)
index 0000000..7b2746c
--- /dev/null
@@ -0,0 +1,15 @@
+puts "============"
+puts "CR23394"
+puts "============"
+puts ""
+##########################################################################################################
+# Problem with BRepOffset_MakeOffset on a cylindrical face
+##########################################################################################################
+
+restore [locate_data_file CR23394-Circular_tube.brep] sh1
+
+thickshell result sh1 5
+
+set square 128648
+
+set 3dviewer 1