mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-08-19 00:51:21 +02:00
add region support to offset_sweep (module only)
This commit is contained in:
108
rounding.scad
108
rounding.scad
@@ -1412,11 +1412,14 @@ module offset_stroke(path, width=1, rounded=true, start, end, check_valid=true,
|
|||||||
// "chamfer". Use the "chamfer" style offset only in cases where the number of steps is small or just one (such as when using
|
// "chamfer". Use the "chamfer" style offset only in cases where the number of steps is small or just one (such as when using
|
||||||
// the `os_chamfer` profile type).
|
// the `os_chamfer` profile type).
|
||||||
// .
|
// .
|
||||||
|
// The module form only can support a region as input. You can provide different profiles for the cutouts in a region using the `bottom_hole`, `top_hole`
|
||||||
|
// or `ends_hole` parameters.
|
||||||
|
// .
|
||||||
// This module offers four anchor types. The default is "hull" in which VNF anchors are placed on the VNF of the **unrounded** object. You
|
// This module offers four anchor types. The default is "hull" in which VNF anchors are placed on the VNF of the **unrounded** object. You
|
||||||
// can also use "intersect" to get the intersection anchors to the unrounded object. If you prefer anchors that respect the rounding
|
// can also use "intersect" to get the intersection anchors to the unrounded object. If you prefer anchors that respect the rounding
|
||||||
// then use "surf_hull" or "intersect_hull".
|
// then use "surf_hull" or "intersect_hull".
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// path = 2d path (list of points) to extrude
|
// path = 2d path (list of points) to extrude or a region for the module form
|
||||||
// height / length / l / h = total height (including rounded portions, but not extra sections) of the output. Default: combined height of top and bottom end treatments.
|
// height / length / l / h = total height (including rounded portions, but not extra sections) of the output. Default: combined height of top and bottom end treatments.
|
||||||
// bottom / bot = rounding spec for the bottom end
|
// bottom / bot = rounding spec for the bottom end
|
||||||
// top = rounding spec for the top end.
|
// top = rounding spec for the top end.
|
||||||
@@ -1434,6 +1437,9 @@ module offset_stroke(path, width=1, rounded=true, start, end, check_valid=true,
|
|||||||
// angle = default angle for chamfers. Default: 45
|
// angle = default angle for chamfers. Default: 45
|
||||||
// joint = default joint value for smooth roundover.
|
// joint = default joint value for smooth roundover.
|
||||||
// k = default curvature parameter value for "smooth" roundover
|
// k = default curvature parameter value for "smooth" roundover
|
||||||
|
// ends_hole = (module only) rounding spec that applies to top and bottom of holes in a region
|
||||||
|
// bot_hole / bottom_hole = (module only) rounding spec for bottom end of holes in a region
|
||||||
|
// top_hole = (module only) rounding spec for top end of holes in a region
|
||||||
// convexity = convexity setting for use with polyhedron. (module only) Default: 10
|
// convexity = convexity setting for use with polyhedron. (module only) Default: 10
|
||||||
// anchor = Translate so anchor point is at the origin. Default: "base"
|
// anchor = Translate so anchor point is at the origin. Default: "base"
|
||||||
// spin = Rotate this many degrees around Z axis after anchor. Default: 0
|
// spin = Rotate this many degrees around Z axis after anchor. Default: 0
|
||||||
@@ -1573,6 +1579,84 @@ module offset_stroke(path, width=1, rounded=true, start, end, check_valid=true,
|
|||||||
// star = star(5, r=220, ir=130);
|
// star = star(5, r=220, ir=130);
|
||||||
// rounded_star = round_corners(star, cut=flatten(repeat([5,0],5)), $fn=24);
|
// rounded_star = round_corners(star, cut=flatten(repeat([5,0],5)), $fn=24);
|
||||||
// offset_sweep(rounded_star, height=100, top=os_mask(ogee), bottom=os_mask(ogee,out=true));
|
// offset_sweep(rounded_star, height=100, top=os_mask(ogee), bottom=os_mask(ogee,out=true));
|
||||||
|
// Example(3D,NoAxes): Applying to a region, with different profiles for the outside in inside curves.
|
||||||
|
// $fn = 32;
|
||||||
|
// rgn = difference(
|
||||||
|
// [
|
||||||
|
// rect(50, rounding=5),
|
||||||
|
// move([15,15], circle(d=10)),
|
||||||
|
// move([-15,-15], circle(d=10)),
|
||||||
|
// move([0,25], rect([10,7],anchor=BACK,
|
||||||
|
// rounding=[-2,-2,2,2])),
|
||||||
|
// zrot(55, square([4, 100], center=true)),
|
||||||
|
// ellipse([12,4])
|
||||||
|
// ]
|
||||||
|
// );
|
||||||
|
// offset_sweep(rgn, height=12, steps=6, ends_hole=os_chamfer(width=2),
|
||||||
|
// ends=os_circle(r=1.7));
|
||||||
|
|
||||||
|
|
||||||
|
module _offset_sweep_region(region, height,
|
||||||
|
bottom, top,
|
||||||
|
h, l, length, ends, bot, top_hole, bot_hole, bottom_hole, ends_hole,
|
||||||
|
offset="round", r=0, steps=16,
|
||||||
|
quality=1, check_valid=true,
|
||||||
|
extra=0,
|
||||||
|
cut=undef, chamfer_width=undef, chamfer_height=undef,
|
||||||
|
joint=undef, k=0.75, angle=45,
|
||||||
|
convexity=10,anchor="base",cp="centroid",
|
||||||
|
spin=0, orient=UP, atype="hull")
|
||||||
|
{
|
||||||
|
connected_reg = region_parts(region);
|
||||||
|
vnf_h_list = [for(reg=connected_reg)
|
||||||
|
offset_sweep(path=reg[0], height=height, h=h, l=l, length=length, bot=bot, top=top, bottom=bottom, ends=ends,
|
||||||
|
offset=offset, r=r, steps=steps,
|
||||||
|
quality=quality, check_valid=check_valid, extra=extra, cut=cut, chamfer_width=chamfer_width,
|
||||||
|
chamfer_height=chamfer_height, joint=joint, k=k, angle=angle, _return_height=true)];
|
||||||
|
vnf_list = column(vnf_h_list,0);
|
||||||
|
height = vnf_h_list[0][1];
|
||||||
|
|
||||||
|
holes = [for(reg=connected_reg, i=[1:1:len(reg)-1]) reg[i]];
|
||||||
|
|
||||||
|
anchors = [
|
||||||
|
named_anchor("zcenter", [0,0,0], UP),
|
||||||
|
named_anchor("base", [0,0,-height/2], UP),
|
||||||
|
named_anchor("top", [0,0,height/2], UP)
|
||||||
|
];
|
||||||
|
bottom_hole=first_defined([bottom_hole, bot_hole, ends_hole, bottom, ends]);
|
||||||
|
top_hole = first_defined([top_hole,ends_hole,top,ends]);
|
||||||
|
if (in_list(atype,["hull","intersect"]))
|
||||||
|
attachable(anchor,spin,orient,region=region,h=height,cp=cp,anchors=anchors,extent=atype=="hull"){
|
||||||
|
down(height/2)
|
||||||
|
difference(){
|
||||||
|
for(vnf=vnf_list)
|
||||||
|
polyhedron(vnf[0],vnf[1],convexity=convexity);
|
||||||
|
for(path=holes)
|
||||||
|
offset_sweep(path=path, height=height, h=h, l=l, length=length, bot=bot, top=top_hole, bottom=bottom_hole,
|
||||||
|
offset=offset, r=r, steps=steps,
|
||||||
|
quality=quality, check_valid=check_valid, extra=extra+0.1, cut=cut, chamfer_width=chamfer_width,
|
||||||
|
chamfer_height=chamfer_height, joint=joint, k=k, angle=angle, _flipdir=true,convexity=convexity);
|
||||||
|
}
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
allvnf=vnf_join(vnf_list);
|
||||||
|
attachable(anchor,spin.orient,vnf=allvnf, cp=cp,anchors=anchors, extent = atype=="surf_hull"){
|
||||||
|
difference(){
|
||||||
|
for(vnf=vnf_list)
|
||||||
|
vnf_polyhedron(vnf,convexity=convexity);
|
||||||
|
for(path=holes)
|
||||||
|
offset_sweep(path=path, height=height, h=h, l=l, length=length, bot=bot, top=top_hole, bottom=bottom_hole,
|
||||||
|
offset=offset, r=r, steps=steps,
|
||||||
|
quality=quality, check_valid=check_valid, extra=extra+0.1, cut=cut, chamfer_width=chamfer_width,
|
||||||
|
chamfer_height=chamfer_height, joint=joint, k=k, angle=angle, _flipdir=true,convexity=convexity);
|
||||||
|
}
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// This function does the actual work of repeatedly calling offset() and concatenating the resulting face and vertex lists to produce
|
// This function does the actual work of repeatedly calling offset() and concatenating the resulting face and vertex lists to produce
|
||||||
@@ -1630,7 +1714,7 @@ function offset_sweep(
|
|||||||
extra=0, caps=true,
|
extra=0, caps=true,
|
||||||
cut=undef, chamfer_width=undef, chamfer_height=undef,
|
cut=undef, chamfer_width=undef, chamfer_height=undef,
|
||||||
joint=undef, k=0.75, angle=45, anchor="base", orient=UP, spin=0,atype="hull", cp="centroid",
|
joint=undef, k=0.75, angle=45, anchor="base", orient=UP, spin=0,atype="hull", cp="centroid",
|
||||||
_return_height=false
|
_return_height=false, _flipdir=false
|
||||||
) =
|
) =
|
||||||
let(
|
let(
|
||||||
argspec = [
|
argspec = [
|
||||||
@@ -1668,8 +1752,9 @@ function offset_sweep(
|
|||||||
)
|
)
|
||||||
assert(offsetsok,"Offsets must be one of \"round\", \"delta\", or \"chamfer\"")
|
assert(offsetsok,"Offsets must be one of \"round\", \"delta\", or \"chamfer\"")
|
||||||
let(
|
let(
|
||||||
offsets_bot = _rounding_offsets(bottom, -1),
|
do_flip = _flipdir ? function(x) xflip(x) : function(x) x ,
|
||||||
offsets_top = _rounding_offsets(top, 1),
|
offsets_bot = do_flip(_rounding_offsets(bottom, -1)),
|
||||||
|
offsets_top = do_flip(_rounding_offsets(top, 1)),
|
||||||
dummy = (struct_val(top,"offset")=="chamfer" && len(offsets_top)>5)
|
dummy = (struct_val(top,"offset")=="chamfer" && len(offsets_top)>5)
|
||||||
|| (struct_val(bottom,"offset")=="chamfer" && len(offsets_bot)>5)
|
|| (struct_val(bottom,"offset")=="chamfer" && len(offsets_bot)>5)
|
||||||
? echo("WARNING: You have selected offset=\"chamfer\", which leads to exponential growth in the vertex count and requested more than 5 layers. This can be slow or run out of recursion depth.")
|
? echo("WARNING: You have selected offset=\"chamfer\", which leads to exponential growth in the vertex count and requested more than 5 layers. This can be slow or run out of recursion depth.")
|
||||||
@@ -1722,22 +1807,30 @@ function offset_sweep(
|
|||||||
: reorient(anchor,spin,orient, vnf=vnf, p=vnf, extent=atype=="surf_hull", cp=cp, anchors=anchors)
|
: reorient(anchor,spin,orient, vnf=vnf, p=vnf, extent=atype=="surf_hull", cp=cp, anchors=anchors)
|
||||||
) _return_height ? [final_vnf,height] : final_vnf;
|
) _return_height ? [final_vnf,height] : final_vnf;
|
||||||
|
|
||||||
|
|
||||||
module offset_sweep(path, height,
|
module offset_sweep(path, height,
|
||||||
bottom, top,
|
bottom, top,
|
||||||
h, l, length, ends, bot,
|
h, l, length, ends, bot,
|
||||||
offset="round", r=0, steps=16,
|
offset="round", r=0, steps=16,
|
||||||
quality=1, check_valid=true,
|
quality=1, check_valid=true,
|
||||||
extra=0,
|
extra=0, top_hole, bot_hole, bottom_hole, ends_hole,
|
||||||
cut=undef, chamfer_width=undef, chamfer_height=undef,
|
cut=undef, chamfer_width=undef, chamfer_height=undef,
|
||||||
joint=undef, k=0.75, angle=45,
|
joint=undef, k=0.75, angle=45,
|
||||||
convexity=10,anchor="base",cp="centroid",
|
convexity=10,anchor="base",cp="centroid",
|
||||||
spin=0, orient=UP, atype="hull")
|
spin=0, orient=UP, atype="hull", _flipdir)
|
||||||
{
|
{
|
||||||
assert(in_list(atype, ["intersect","hull","surf_hull","surf_intersect"]), "Anchor type must be \"hull\" or \"intersect\"");
|
assert(in_list(atype, ["intersect","hull","surf_hull","surf_intersect"]), "Anchor type must be \"hull\" or \"intersect\"");
|
||||||
|
if (is_region(path) && len(path)>1)
|
||||||
|
_offset_sweep_region(region=path, height=height, bottom=bottom, top=top, h=h, l=l, length=length, ends=ends, bot=bot,
|
||||||
|
offset=offset, r=r, steps=steps, quality=quality, check_valid=check_valid, extra=extra,
|
||||||
|
cut=cut, chamfer_width=chamfer_width, chamfer_height=chamfer_height, joint=joint, k=k, angle=angle,
|
||||||
|
bot_hole=bot_hole,top_hole=top_hole,bottom_hole=bottom_hole,ends_hole=ends_hole,
|
||||||
|
convexity=convexity, anchor=anchor, cp=cp, spin=spin, orient=orient, atype=atype) children();
|
||||||
|
else {
|
||||||
vnf_h = offset_sweep(path=path, height=height, h=h, l=l, length=length, bot=bot, top=top, bottom=bottom, ends=ends,
|
vnf_h = offset_sweep(path=path, height=height, h=h, l=l, length=length, bot=bot, top=top, bottom=bottom, ends=ends,
|
||||||
offset=offset, r=r, steps=steps,
|
offset=offset, r=r, steps=steps,
|
||||||
quality=quality, check_valid=check_valid, extra=extra, cut=cut, chamfer_width=chamfer_width,
|
quality=quality, check_valid=check_valid, extra=extra, cut=cut, chamfer_width=chamfer_width,
|
||||||
chamfer_height=chamfer_height, joint=joint, k=k, angle=angle, _return_height=true);
|
chamfer_height=chamfer_height, joint=joint, k=k, angle=angle, _return_height=true, _flipdir=_flipdir);
|
||||||
vnf = vnf_h[0];
|
vnf = vnf_h[0];
|
||||||
height = vnf_h[1];
|
height = vnf_h[1];
|
||||||
anchors = [
|
anchors = [
|
||||||
@@ -1755,6 +1848,7 @@ module offset_sweep(path, height,
|
|||||||
vnf_polyhedron(vnf,convexity=convexity);
|
vnf_polyhedron(vnf,convexity=convexity);
|
||||||
children();
|
children();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -903,9 +903,11 @@ function linear_sweep(
|
|||||||
// .
|
// .
|
||||||
// If you want to place just one or a few copies of a texture onto an object rather than texturing the entire object you can do that by using
|
// If you want to place just one or a few copies of a texture onto an object rather than texturing the entire object you can do that by using
|
||||||
// and angle smaller than 360. However, if you want to control the aspect ratio of the resulting texture you will have to carefully calculate the proper
|
// and angle smaller than 360. However, if you want to control the aspect ratio of the resulting texture you will have to carefully calculate the proper
|
||||||
// angle to use. To simplify this process you can use `pixel_aspect` or `tex_aspect`. You can set `tex_aspect` for any type of tile and it specifies
|
// angle to use to ensure that the arc length in the horizontal direction is the proper length compared to the arc length in the vertical direction.
|
||||||
|
// To simplify this process you can use `pixel_aspect` or `tex_aspect`. You can set `tex_aspect` for any type of tile and it specifies
|
||||||
// the desired aspect ratio (width/height) for the tiles. You must specify `tex_reps` in order to use this feature. For heightfields you can instead provide
|
// the desired aspect ratio (width/height) for the tiles. You must specify `tex_reps` in order to use this feature. For heightfields you can instead provide
|
||||||
// a pixel aspect ratio, which is suited to the case where your texture is a non-square image that you want to place on a curved object.
|
// a pixel aspect ratio, which is suited to the case where your texture is a non-square image that you want to place on a curved object. For a simple cylinder
|
||||||
|
// it is obvious what the horizontal arc length is; for other objects this is computed based on the average radius of the longest path in `shape`.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// shape = The polygon or [region](regions.scad) to sweep around the Z axis.
|
// shape = The polygon or [region](regions.scad) to sweep around the Z axis.
|
||||||
// angle = If given, specifies the number of degrees to sweep the region around the Z axis, counterclockwise from the X+ axis. Default: 360 (full rotation)
|
// angle = If given, specifies the number of degrees to sweep the region around the Z axis, counterclockwise from the X+ axis. Default: 360 (full rotation)
|
||||||
|
Reference in New Issue
Block a user