New feature: Part Offset2D

Info about new implemented features, classes, modules or APIs. Might get technical!
Posts: 4466
Joined: Fri Aug 29, 2014 12:45 am
Location: Saint-Petersburg, Russia

Re: New feature: Part Offset2D

Postby DeepSOIC » Mon Oct 03, 2016 9:08 pm

I have experimented a little bit with circles.
When I move the circle within the sketch, the offset follows. However if I move the sketch itself, the offset is moved by twice the amount.
Same thing with Draft, except there is no way to move Draft Circle internally.
Screening Placement off Part Offset2d by making compound from the sketch/circle doesn't fix the problem. However, absorbing the placement with .transformShape method seems to fix this problem.

Furthermore, if I make the sketch circle on XZ plane, the offset result is on XY plane.

The problem is very specific to circles. Rectangle and ellipse work fine for me. So I would call it an OCC bug for now.
Posts: 103
Joined: Tue Jan 03, 2017 10:55 am

Re: New feature: Part Offset2D

Postby realthunder » Tue Jan 03, 2017 4:20 pm

I was able to locate and fix the circle bug in OCC. In case anyone need it, I include the patch below. The patch is against OCC 7.1.0. The bug affects circles having a transformed supporting plane. Since OCE hasn't caught up with OCC 7, I think FreeCAD shall host a fork of the OCC.

Unfortunately, there are other bugs in OCC makeOffset. And after spending days trying to hunt down the problem, I conclude that OCC makeOffset is just beyond help, with my knowledge at least. After searching around for alternatives to do 2D offset, I found the wonderful ClipperLib. And it turns out, FreeCAD already has this library! What do you know! I have submitted a pull request regarding this.

Code: Select all

diff --git a/src/BRepFill/BRepFill_OffsetWire.cxx b/src/BRepFill/BRepFill_OffsetWire.cxx
index 5cc63bd..2540e5a 100755
--- a/src/BRepFill/BRepFill_OffsetWire.cxx
+++ b/src/BRepFill/BRepFill_OffsetWire.cxx
@@ -293,12 +293,17 @@ static Standard_Boolean KPartCircle
       OC = new Geom2d_OffsetCurve( G2dT, anOffset);
     Handle(Geom_Surface) aSurf = BRep_Tool::Surface(mySpine);
+    if (!L.IsIdentity()) {
+        Handle(Geom_Geometry) aCopy = aSurf->Transformed(L.Inverted().Transformation());
+        aSurf = Handle(Geom_Surface)(static_cast<Geom_Surface*>(aCopy.get()));
+    }
     Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(aSurf);
-    myShape = BRepLib_MakeEdge(OC, aPlane, f, l);
+    myShape = BRepLib_MakeEdge(OC, aSurf, f, l);
     if (fabs(Alt) > gp::Resolution()) {
       BRepAdaptor_Surface S(mySpine,0);
       gp_Ax1 Nor = S.Plane().Axis();