Skip to content

Commit d677495

Browse files
committed
Add cutpath_centered to partition functions
Fixes #1692 When tweaking cutsize and gap, the whole cut pattern can suddenly shift by half (cutsize+gap), which is really annoying. This change causes the cut pattern to always be centered on X=0. Possibly controversially, it also makes this the default behaviour, which is backwards-incompatible.
1 parent eeea026 commit d677495

File tree

1 file changed

+26
-19
lines changed

1 file changed

+26
-19
lines changed

partitions.scad

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ function _partition_subpath(type) =
401401
assert(false, str("Unsupported cutpath type: ", type));
402402

403403

404-
function _partition_cutpath(l, h, cutsize, cutpath, gap) =
404+
function _partition_cutpath(l, h, cutsize, cutpath, gap, cutpath_centered) =
405405
let(
406406
check = assert(is_finite(l))
407407
assert(is_finite(h))
@@ -411,7 +411,8 @@ function _partition_cutpath(l, h, cutsize, cutpath, gap) =
411411
cutsize = is_vector(cutsize)? cutsize : [cutsize*2, cutsize],
412412
cutpath = is_path(cutpath)? cutpath :
413413
_partition_subpath(cutpath),
414-
reps = ceil(l/(cutsize.x+gap)),
414+
reps_raw = ceil(l/(cutsize.x+gap)),
415+
reps = reps_raw%2==0 && cutpath_centered ? reps_raw+1 : reps_raw,
415416
cplen = (cutsize.x+gap) * reps,
416417
path = deduplicate(concat(
417418
[[-l/2, cutpath[0].y*cutsize.y]],
@@ -443,16 +444,18 @@ function _partition_cutpath(l, h, cutsize, cutpath, gap) =
443444
// cutsize = The width of the cut pattern to be used.
444445
// cutpath = The cutpath to use. Standard named paths are "flat", "sawtooth", "sinewave", "comb", "finger", "dovetail", "hammerhead", and "jigsaw". Alternatively, you can give a cutpath as a 2D path, where X is between 0 and 1, and Y is between -0.5 and 0.5.
445446
// gap = Empty gaps between cutpath iterations. Default: 0
447+
// cutpath_centered = Ensures the cutpath is always centered. Default: true
446448
// inverse = If true, create a cutpath that is meant to mate to a non-inverted cutpath.
447449
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
448450
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
449451
// $slop = The amount to shrink the mask by, to correct for printer-specific fitting.
450452
// Examples:
451453
// partition_mask(w=50, gap=0, cutpath="jigsaw");
452-
// partition_mask(w=50, gap=30, cutpath="jigsaw");
453-
// partition_mask(w=50, gap=30, cutpath="jigsaw", inverse=true);
454-
// partition_mask(w=50, gap=30, cutsize=15, cutpath="jigsaw");
455-
// partition_mask(w=50, cutsize=[20,20], gap=30, cutpath="jigsaw");
454+
// partition_mask(w=50, gap=10, cutpath="jigsaw");
455+
// partition_mask(w=50, gap=10, cutpath="jigsaw", inverse=true);
456+
// partition_mask(w=50, gap=10, cutsize=4, cutpath="jigsaw");
457+
// partition_mask(w=50, gap=10, cutsize=4, cutpath="jigsaw", cutpath_centered=false);
458+
// partition_mask(w=50, gap=10, cutsize=[4,20], cutpath="jigsaw");
456459
// Examples(2D):
457460
// partition_mask(w=20, cutpath="sawtooth");
458461
// partition_mask(w=20, cutpath="sinewave");
@@ -461,10 +464,10 @@ function _partition_cutpath(l, h, cutsize, cutpath, gap) =
461464
// partition_mask(w=20, cutpath="dovetail");
462465
// partition_mask(w=20, cutpath="hammerhead");
463466
// partition_mask(w=20, cutpath="jigsaw");
464-
module partition_mask(l=100, w=100, h=100, cutsize=10, cutpath="jigsaw", gap=0, inverse=false, anchor=CENTER, spin=0, orient=UP)
467+
module partition_mask(l=100, w=100, h=100, cutsize=10, cutpath="jigsaw", gap=0, cutpath_centered=true, inverse=false, anchor=CENTER, spin=0, orient=UP)
465468
{
466469
cutsize = is_vector(cutsize)? point2d(cutsize) : [cutsize*2, cutsize];
467-
path = _partition_cutpath(l, h, cutsize, cutpath, gap);
470+
path = _partition_cutpath(l, h, cutsize, cutpath, gap, cutpath_centered);
468471
midpath = select(path,1,-2);
469472
sizepath = concat([path[0]+[-get_slop(),0]], midpath, [last(path)+[get_slop(),0]], [[+(l/2+get_slop()), (w+get_slop())*(inverse?-1:1)], [-(l/2+get_slop()), (w+get_slop())*(inverse?-1:1)]]);
470473
bnds = pointlist_bounds(sizepath);
@@ -498,14 +501,16 @@ module partition_mask(l=100, w=100, h=100, cutsize=10, cutpath="jigsaw", gap=0,
498501
// cutsize = The width of the cut pattern to be used. Default: 10
499502
// cutpath = The cutpath to use. Standard named paths are "flat", "sawtooth", "sinewave", "comb", "finger", "dovetail", "hammerhead", and "jigsaw". Alternatively, you can give a cutpath as a 2D path, where X is between 0 and 1, and Y is between -0.5 and 0.5. Default: "jigsaw"
500503
// gap = Empty gaps between cutpath iterations. Default: 0
504+
// cutpath_centered = Ensures the cutpath is always centered. Default: true
501505
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
502506
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
503507
// $slop = The width of the cut mask, to correct for printer-specific fitting.
504508
// Examples:
505509
// partition_cut_mask(gap=0, cutpath="dovetail");
506-
// partition_cut_mask(gap=30, cutpath="dovetail");
507-
// partition_cut_mask(gap=30, cutsize=15, cutpath="dovetail");
508-
// partition_cut_mask(gap=30, cutsize=[20,20], cutpath="dovetail");
510+
// partition_cut_mask(gap=10, cutpath="dovetail");
511+
// partition_cut_mask(gap=10, cutsize=15, cutpath="dovetail");
512+
// partition_cut_mask(gap=10, cutsize=[15,15], cutpath="dovetail");
513+
// partition_cut_mask(gap=10, cutsize=[15,15], cutpath="dovetail", cutpath_centered=false);
509514
// Examples(2DMed):
510515
// partition_cut_mask(cutpath="sawtooth",$slop=0.5);
511516
// partition_cut_mask(cutpath="sinewave",$slop=0.5);
@@ -514,10 +519,10 @@ module partition_mask(l=100, w=100, h=100, cutsize=10, cutpath="jigsaw", gap=0,
514519
// partition_cut_mask(cutpath="dovetail",$slop=1);
515520
// partition_cut_mask(cutpath="hammerhead",$slop=1);
516521
// partition_cut_mask(cutpath="jigsaw",$slop=0.5);
517-
module partition_cut_mask(l=100, h=100, cutsize=10, cutpath="jigsaw", gap=0, anchor=CENTER, spin=0, orient=UP)
522+
module partition_cut_mask(l=100, h=100, cutsize=10, cutpath="jigsaw", gap=0, cutpath_centered=true, anchor=CENTER, spin=0, orient=UP)
518523
{
519524
cutsize = is_vector(cutsize)? cutsize : [cutsize*2, cutsize];
520-
path = _partition_cutpath(l, h, cutsize, cutpath, gap);
525+
path = _partition_cutpath(l, h, cutsize, cutpath, gap, cutpath_centered);
521526
attachable(anchor,spin,orient, size=[l,cutsize.y,h]) {
522527
linear_extrude(height=h, center=true, convexity=10) {
523528
stroke(path, width=max(0.1, get_slop()*2));
@@ -542,14 +547,16 @@ module partition_cut_mask(l=100, h=100, cutsize=10, cutpath="jigsaw", gap=0, anc
542547
// cutsize = The width of the cut pattern to be used.
543548
// cutpath = The cutpath to use. Standard named paths are "flat", "sawtooth", "sinewave", "comb", "finger", "dovetail", "hammerhead", and "jigsaw". Alternatively, you can give a cutpath as a 2D path, where X is between 0 and 1, and Y is between -0.5 and 0.5.
544549
// gap = Empty gaps between cutpath iterations. Default: 0
550+
// cutpath_centered = Ensures the cutpath is always centered. Default: true
545551
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
546552
// ---
547553
// $slop = Extra gap to leave to correct for printer-specific fitting.
548554
// Examples(Med):
549555
// partition(spread=12, cutpath="dovetail") cylinder(h=50, d=80, center=false);
550-
// partition(spread=12, gap=30, cutpath="dovetail") cylinder(h=50, d=80, center=false);
551-
// partition(spread=20, gap=20, cutsize=15, cutpath="dovetail") cylinder(h=50, d=80, center=false);
552-
// partition(spread=25, gap=15, cutsize=[20,20], cutpath="dovetail") cylinder(h=50, d=80, center=false);
556+
// partition(spread=12, gap=10, cutpath="dovetail") cylinder(h=50, d=80, center=false);
557+
// partition(spread=12, gap=10, cutpath="dovetail", cutpath_centered=false) cylinder(h=50, d=80, center=false);
558+
// partition(spread=20, gap=10, cutsize=15, cutpath="dovetail") cylinder(h=50, d=80, center=false);
559+
// partition(spread=25, gap=10, cutsize=[20,20], cutpath="dovetail") cylinder(h=50, d=80, center=false);
553560
// Side Effects:
554561
// `$idx` is set to 0 on the back part and 1 on the front part.
555562
// Examples(2DMed):
@@ -560,7 +567,7 @@ module partition_cut_mask(l=100, h=100, cutsize=10, cutpath="jigsaw", gap=0, anc
560567
// partition(spread=12, cutpath="dovetail") cylinder(h=50, d=80, center=false);
561568
// partition(spread=12, cutpath="hammerhead") cylinder(h=50, d=80, center=false);
562569
// partition(cutpath="jigsaw") cylinder(h=50, d=80, center=false);
563-
module partition(size=100, spread=10, cutsize=10, cutpath="jigsaw", gap=0, spin=0)
570+
module partition(size=100, spread=10, cutsize=10, cutpath="jigsaw", gap=0, cutpath_centered=true, spin=0)
564571
{
565572
req_children($children);
566573
size = is_vector(size)? size : [size,size,size];
@@ -571,14 +578,14 @@ module partition(size=100, spread=10, cutsize=10, cutpath="jigsaw", gap=0, spin=
571578
$idx = 0;
572579
intersection() {
573580
children();
574-
partition_mask(l=rsize.x, w=rsize.y, h=rsize.z, cutsize=cutsize, cutpath=cutpath, gap=gap, spin=spin);
581+
partition_mask(l=rsize.x, w=rsize.y, h=rsize.z, cutsize=cutsize, cutpath=cutpath, gap=gap, cutpath_centered=cutpath_centered, spin=spin);
575582
}
576583
}
577584
move(-vec) {
578585
$idx = 1;
579586
intersection() {
580587
children();
581-
partition_mask(l=rsize.x, w=rsize.y, h=rsize.z, cutsize=cutsize, cutpath=cutpath, gap=gap, inverse=true, spin=spin);
588+
partition_mask(l=rsize.x, w=rsize.y, h=rsize.z, cutsize=cutsize, cutpath=cutpath, gap=gap, cutpath_centered=cutpath_centered, inverse=true, spin=spin);
582589
}
583590
}
584591
}

0 commit comments

Comments
 (0)