Add inner_corner default setting

to allow removing the loops in inner corners

Related: #294
This commit is contained in:
Florian Festi 2022-03-20 00:21:57 +01:00
parent b12fded50d
commit a7063011b5
4 changed files with 36 additions and 10 deletions

View File

@ -298,6 +298,10 @@ class Boxes:
defaultgroup.add_argument( defaultgroup.add_argument(
"--reference", action="store", type=float, default=100, "--reference", action="store", type=float, default=100,
help="print reference rectangle with given length (in mm)(zero to disable) [\U0001F6C8](https://florianfesti.github.io/boxes/html/usermanual.html#reference)") help="print reference rectangle with given length (in mm)(zero to disable) [\U0001F6C8](https://florianfesti.github.io/boxes/html/usermanual.html#reference)")
defaultgroup.add_argument(
"--inner_corners", action="store", type=str, default="loop",
choices=["loop", "corner", "backarc"],
help="style for inner corners [\U0001F6C8](https://florianfesti.github.io/boxes/html/usermanual.html#inner-corners)")
defaultgroup.add_argument( defaultgroup.add_argument(
"--burn", action="store", type=float, default=0.1, "--burn", action="store", type=float, default=0.1,
help='burn correction (in mm)(bigger values for tighter fit) [\U0001F6C8](https://florianfesti.github.io/boxes/html/usermanual.html#burn)') help='burn correction (in mm)(bigger values for tighter fit) [\U0001F6C8](https://florianfesti.github.io/boxes/html/usermanual.html#burn)')
@ -671,7 +675,7 @@ class Boxes:
self.surface.set_metadata(self.metadata) self.surface.set_metadata(self.metadata)
self.surface.flush() self.surface.flush()
self.surface.finish() self.surface.finish(self.inner_corners)
self.formats.convert(self.output, self.format, self.metadata) self.formats.convert(self.output, self.format, self.metadata)
if self.inkscapefile: if self.inkscapefile:

View File

@ -186,7 +186,10 @@ class Path:
if invert_y: if invert_y:
c[3] *= Affine.scale(1, -1) c[3] *= Affine.scale(1, -1)
def faster_edges(self): def faster_edges(self, inner_corners):
if inner_corners == "backarc":
return
for (i, p) in enumerate(self.path): for (i, p) in enumerate(self.path):
if p[0] == "C" and i > 1 and i < len(self.path) - 1: if p[0] == "C" and i > 1 and i < len(self.path) - 1:
if self.path[i - 1][0] == "L" and self.path[i + 1][0] == "L": if self.path[i - 1][0] == "L" and self.path[i + 1][0] == "L":
@ -200,8 +203,12 @@ class Path:
lines_intersect, x, y = line_intersection((p11, p12), (p21, p22)) lines_intersect, x, y = line_intersection((p11, p12), (p21, p22))
if lines_intersect: if lines_intersect:
self.path[i - 1] = ("L", x, y) self.path[i - 1] = ("L", x, y)
self.path[i] = ("C", x, y, *p12, *p21) if inner_corners == "loop":
self.path[i] = ("C", x, y, *p12, *p21)
else:
self.path[i] = ("L", x, y)
# filter duplicates
self.path = [p for n, p in enumerate(self.path) if p != self.path[n-1]]
class Context: class Context:
def __init__(self, surface, *al, **ad): def __init__(self, surface, *al, **ad):
@ -460,7 +467,7 @@ Creation date: {date}
m.tail = '\n' m.tail = '\n'
root.insert(0, m) root.insert(0, m)
def finish(self): def finish(self, inner_corners="loop"):
extents = self._adjust_coordinates() extents = self._adjust_coordinates()
w = extents.width * self.scale w = extents.width * self.scale
h = extents.height * self.scale h = extents.height * self.scale
@ -498,7 +505,7 @@ Creation date: {date}
x, y = 0, 0 x, y = 0, 0
start = None start = None
last = None last = None
path.faster_edges() path.faster_edges(inner_corners)
for c in path.path: for c in path.path:
x0, y0 = x, y x0, y0 = x, y
C, x, y = c[0:3] C, x, y = c[0:3]
@ -602,7 +609,7 @@ class PSSurface(Surface):
desc += f'%%SettingsUrl: {md["url"].replace("&render=1", "")}\n' desc += f'%%SettingsUrl: {md["url"].replace("&render=1", "")}\n'
return desc return desc
def finish(self): def finish(self, inner_corners="loop"):
extents = self._adjust_coordinates() extents = self._adjust_coordinates()
w = extents.width w = extents.width
@ -644,7 +651,7 @@ class PSSurface(Surface):
for j, path in enumerate(part.pathes): for j, path in enumerate(part.pathes):
p = [] p = []
x, y = 0, 0 x, y = 0, 0
path.faster_edges() path.faster_edges(inner_corners)
for c in path.path: for c in path.path:
x0, y0 = x, y x0, y0 = x, y

View File

@ -32,12 +32,12 @@ Unfortunately some formats do not save the units of measurement or don't do so p
Why are there tiny, weird loops in the corners? Why are there tiny, weird loops in the corners?
----------------------------------------------- -----------------------------------------------
These are called dog bones and make sure the corner is completely cut out. As lasers and milling tools are round they can't cut sharp inner corners. Have a look at :doc:`burn correction details <api_burn>`. These are called dog bones and make sure the corner is completely cut out. As lasers and milling tools are round they can't cut sharp inner corners. Have a look at :doc:`burn correction details <api_burn>` for details.
I really don't want those weird, tiny loops? I really don't want those weird, tiny loops?
-------------------------------------------- --------------------------------------------
You can just set ``burn`` to ``0`` to make them go away. But you have then to use a separate CAM software to do the burn correction (aka kerf). Or your laser cutter software may be able to take care of that. You can set the ``inner_corners`` default setting to ``corner``
What settings were used to generate a drawing? What settings were used to generate a drawing?
---------------------------------------------- ----------------------------------------------

View File

@ -117,6 +117,21 @@ For plywood values of 0.2 to 0.3mm still allow getting the parts out
by hand (Depending on you laser cutter and the exact material). With by hand (Depending on you laser cutter and the exact material). With
little more you will need a knife to cut them loose. little more you will need a knife to cut them loose.
inner_corners
.............
How to handle inner corners. Inner corners are an issue as a round
tool like a laser or mill cannot create sharp inner corners. There are
different options:
* ``loop`` create a loop that fills the corner
* ``corner`` just a simple sharp corner in the path that will leave a
radius untouched.
* ``backarc`` naive implementation with inverted arcs connection the
straight lines.
See also :doc:`burn correction details <api_burn>`
debug debug
..... .....