cadquery icon indicating copy to clipboard operation
cadquery copied to clipboard

Offset2D of circle changes Z-plane

Open MarSik opened this issue 4 years ago • 7 comments

I am trying to make two concentric circles on the top face of a box for further extrusion. However this code produces two circles with the right offset, but in different Z planes.

r = cq.Workplane("XY")
r = r.box(1,1,1)
r = r.faces(">Z")
r = r.circle(0.75)
r = r.tag("c")

r = r.offset2D(0.1)
show_object(r)

r = r.wires(tag="c")
show_object(r)

offset

I found a similar issue in FreeCAD (https://tracker.freecadweb.org/view.php?id=3020) and it seems they had to manipulate the location before executing the offset2d operation: https://github.com/FreeCAD/FreeCAD/commit/dbc09e3a2342af8784045d3d0ae3565ec869bef6

MarSik avatar Oct 03 '21 22:10 MarSik

This could be related to issue #753

MarSik avatar Oct 03 '21 22:10 MarSik

I would just like to add that this works fine with a rectangle:

r = cq.Workplane("XY")
r = r.box(1,1,1)
r = r.faces(">Z")
r = r.rect(0.75, 0.75)
r = r.tag("c")

r = r.offset2D(0.1)
show_object(r)

r = r.wires(tag="c")
show_object(r)

offset-rect

MarSik avatar Oct 04 '21 06:10 MarSik

Confirmed

adam-urbanczyk avatar Oct 04 '21 06:10 adam-urbanczyk

Spotted this issue from a HN thread where users were desperately trying to dig out reasons to justify keep using OpenSCAD.

Any idea if this issue exists on OpenCASCADE bug tracker? I can't find a matching one.

@adam-urbanczyk should I implement a similar workaround as in FreeCAD? Something like

  1. (Optional I think?) Apply the trick only on wires with a single edge
  2. Store the original wire.wrapped.Location()
  3. Reset the original wire.wrapped.Location to TopLoc_Location()
  4. Apply BRepOffsetAPI_MakeOffset
  5. Restore Location to the original wire and the resulting shape(s)

Also just to document this somewhere online, I poked at the Inversion trick pointed out by Chris_G in the FreeCAD thread.

Mildly interestingly the trick needs to be applied only to the location of C2, subsequent C3 and C4 end up right where they should.

from cadquery import cq

box = cq.Workplane("XY").box(1, 1, 1)

c1 = box.faces(">Y").workplane().circle(0.75)
c1_loc = c1.objects[0].wrapped.Location().Inverted()

c2 = c1.offset2D(0.1)
# Workaround bug 896
c2.objects[0].wrapped.Location(c1_loc)

c3 = c2.offset2D(0.1)
c4 = c3.offset2D(0.1)

show_object(box, 'box')
show_object(c1, 'c1')
show_object(c2, 'c2')
show_object(c3, 'c3')
show_object(c4, 'c4')

voneiden avatar Feb 07 '22 08:02 voneiden

OCCT 7.6.0 has two commits that touch the circle offsetting algorithm. The latter one sounds promising.

https://github.com/Open-Cascade-SAS/OCCT/commit/7e187d6b22e782161450fbf09c5c7563faaecc66

https://github.com/Open-Cascade-SAS/OCCT/commit/55b5d19bd8d1a1803be5d53055d03db50e5af64d

Edit: Since afaik OCCT 7.6.0 is gonna land into CQ pretty soon best to just see if this this gets resolved.

voneiden avatar Feb 10 '22 07:02 voneiden

Yes, there is a branch for 7.6 already https://github.com/CadQuery/cadquery/tree/occt7.6

adam-urbanczyk avatar Feb 10 '22 07:02 adam-urbanczyk

Replicates still in 7.7.0

voneiden avatar May 15 '23 09:05 voneiden