Change offset() default closed value to match builtin

This commit is contained in:
Adrian Mariano 2024-09-14 17:08:35 -04:00
parent 5580bdaf14
commit d90aeb367f
2 changed files with 10 additions and 7 deletions

View file

@ -1193,7 +1193,7 @@ module rabbit_clip(type, length, width, snap, thickness, depth, compression=0.1
bounds = pointlist_bounds(rounded); bounds = pointlist_bounds(rounded);
extrapt = is_pin ? [] : [rounded[0] - [0,extra]]; extrapt = is_pin ? [] : [rounded[0] - [0,extra]];
finalpath = is_pin ? rounded finalpath = is_pin ? rounded
: let(withclearance=offset(rounded, r=-clearance)) : let(withclearance=offset(rounded, r=-clearance, closed=false))
concat( [[withclearance[0].x,-extra]], concat( [[withclearance[0].x,-extra]],
withclearance, withclearance,
[[-withclearance[0].x,-extra]]); [[-withclearance[0].x,-extra]]);

View file

@ -814,8 +814,10 @@ function _point_dist(path,pathseg_unit,pathseg_len,pt) =
// Takes a 2D input path, polygon or region and returns a path offset by the specified amount. As with the built-in // Takes a 2D input path, polygon or region and returns a path offset by the specified amount. As with the built-in
// offset() module, you can use `r` to specify rounded offset and `delta` to specify offset with // offset() module, you can use `r` to specify rounded offset and `delta` to specify offset with
// corners. If you used `delta` you can set `chamfer` to true to get chamfers. // corners. If you used `delta` you can set `chamfer` to true to get chamfers.
// For paths and polygons positive offsets make the polygons larger. For paths, // When `closed=true` (the default), the input is treated as a polygon. If the input is a region it is treated as a collection
// positive offsets shift the path to the left, relative to the direction of the path. // of polygons. In this case, positive offset values make the shape larger. If you set `closed=false` then the input is treated as a path
// with distinct start and end points. For paths, positive offsets shifts the path to the left, relative to the direction of the path.
// Note that a path that happens to end at its starting point is not the same as a polygon and the offset result may differ.
// . // .
// If you use `delta` without chamfers, the path must not include any 180 degree turns, where the path // If you use `delta` without chamfers, the path must not include any 180 degree turns, where the path
// reverses direction. Such reversals result in an offset with two parallel segments, so they cannot be // reverses direction. Such reversals result in an offset with two parallel segments, so they cannot be
@ -863,7 +865,7 @@ function _point_dist(path,pathseg_unit,pathseg_len,pt) =
// r = offset radius. Distance to offset. Will round over corners. // r = offset radius. Distance to offset. Will round over corners.
// delta = offset distance. Distance to offset with pointed corners. // delta = offset distance. Distance to offset with pointed corners.
// chamfer = chamfer corners when you specify `delta`. Default: false // chamfer = chamfer corners when you specify `delta`. Default: false
// closed = if true path is treate as a polygon. Default: False. // closed = if true path is treated as a polygon. Default: True.
// check_valid = perform segment validity check. Default: True. // check_valid = perform segment validity check. Default: True.
// quality = validity check quality parameter, a small integer. Default: 1. // quality = validity check quality parameter, a small integer. Default: 1.
// same_length = return a path with the same length as the input. Only compatible with `delta=`. Default: false // same_length = return a path with the same length as the input. Only compatible with `delta=`. Default: false
@ -902,7 +904,7 @@ function _point_dist(path,pathseg_unit,pathseg_len,pt) =
// Example(2D): Open path. The red path moves from left to right as shown by the arrow and the positive offset shifts to the left of the initial red path. // Example(2D): Open path. The red path moves from left to right as shown by the arrow and the positive offset shifts to the left of the initial red path.
// sinpath = 2*[for(theta=[-180:5:180]) [theta/4,45*sin(theta)]]; // sinpath = 2*[for(theta=[-180:5:180]) [theta/4,45*sin(theta)]];
// stroke(sinpath, width=2, color="red", endcap2="arrow2"); // stroke(sinpath, width=2, color="red", endcap2="arrow2");
// stroke(offset(sinpath, r=17.5),width=2); // stroke(offset(sinpath, r=17.5,closed=false),width=2);
// Example(2D,NoAxes): An open path in red with with its positive offset in yellow and its negative offset in blue. // Example(2D,NoAxes): An open path in red with with its positive offset in yellow and its negative offset in blue.
// seg = [[0,0],[0,50]]; // seg = [[0,0],[0,50]];
// stroke(seg,color="red",endcap2="arrow2"); // stroke(seg,color="red",endcap2="arrow2");
@ -985,12 +987,13 @@ function _point_dist(path,pathseg_unit,pathseg_len,pt) =
function offset( function offset(
path, r=undef, delta=undef, chamfer=false, path, r=undef, delta=undef, chamfer=false,
closed=false, check_valid=true, closed=true, check_valid=true,
quality=1, return_faces=false, firstface_index=0, quality=1, return_faces=false, firstface_index=0,
flip_faces=false, same_length=false flip_faces=false, same_length=false
) = ) =
assert(!(same_length && return_faces), "Cannot combine return_faces with same_length") assert(!(same_length && return_faces), "Cannot combine return_faces with same_length")
is_region(path)? is_region(path)?
assert(closed, "cannot set closed=false for a region")
assert(!return_faces, "return_faces not supported for regions.") assert(!return_faces, "return_faces not supported for regions.")
let( let(
ofsregs = [for(R=region_parts(path)) ofsregs = [for(R=region_parts(path))
@ -1035,7 +1038,7 @@ function offset(
cornercheck = [for(i=idx(goodsegs)) (!closed && (i==0 || i==len(goodsegs)-1)) cornercheck = [for(i=idx(goodsegs)) (!closed && (i==0 || i==len(goodsegs)-1))
|| is_def(sharpcorners[i]) || is_def(sharpcorners[i])
|| approx(unit(deltas(select(goodsegs,i-1))[0]) * unit(deltas(goodsegs[i])[0]),-1)], || approx(unit(deltas(select(goodsegs,i-1))[0]) * unit(deltas(goodsegs[i])[0]),-1)],
dummyA = assert(len(sharpcorners)==2 || all(cornercheck),"Two consecutive valid offset segments are parallel but do not meet at their ends, maybe because path contains very short segments that were mistakenly flagged as invalid; unable to compute offset"), dummyA = assert(len(sharpcorners)==2 || all(cornercheck),"Two consecutive valid offset segments are parallel but do not meet at their ends, maybe because path contains very short segments that were mistakenly flagged as invalid; unable to compute offset. If you get this error from offset_sweep() try setting ofset=\"delta\""),
reversecheck = reversecheck =
!same_length !same_length
|| !(is_def(delta) && !chamfer) // Reversals only a problem in delta mode without chamfers || !(is_def(delta) && !chamfer) // Reversals only a problem in delta mode without chamfers