Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions attachments.scad
Original file line number Diff line number Diff line change
Expand Up @@ -3367,6 +3367,45 @@ function named_anchor(name, pos, orient, spin, rot, flip, info) =
[name, pos, dir, spin, if (info) info];


// Module: change_anchors()
// Synopsis: Changes the named anchors inherited from the parent
// Topics: Attachments
// See Also: named_anchor(), attachable()
// Usage:
// PARENT() change_anchors([named],[alias=],[remove=]) CHILDREN;
// Description:
// Modifies the named anchors inherited from the parent object. The `named` parameter gives a list
// of new or replacement named anchors, specified in the usual way with {{named_anchor()}}.
// The `alias` parameter specifies a list of string pairs of the form `[newname, oldname]` where
// `newname` is a new anchor name and `oldname` is an existing named anchor for the parent. The
// existing parent anchor will be propagated to the child under the new name. The old name is not changed,
// and will also be propagated to the child. The `remove` parameter removes named anchors inherited from
// the parent so they are not propagated to the child. You can use it to remove an anchor that you have
// aliased so that only the new name propagates to the child.
// Arguments:
// named = list of named anchors to add
// ---
// alias = list of string pairs of the form [newname,oldname] creating named anchor aliases
// remove = list of strings giving anchors to remove

module change_anchors(named=[], alias=[], remove=[])
{
oldanch = last($parent_geom);
allremove = concat(column(named,0), remove);
keepanch = [for(anch=oldanch) if (!in_list(anch[0],allremove)) anch];
aliasanch = [for(name=alias)
let(
found = search([name[1]], oldanch, num_returns_per_match=1)[0]
)
assert(found!=[], str("Alias references unknown anchor: ",name[1]))
list_set(oldanch[found],0,name[0])
];
newanch = concat(keepanch, aliasanch, named);
$parent_geom = list_set($parent_geom,-1,newanch);
children();
}


// Function: attach_geom()
// Synopsis: Returns the internal geometry description of an attachable object.
// Topics: Attachments
Expand Down
50 changes: 32 additions & 18 deletions skin.scad
Original file line number Diff line number Diff line change
Expand Up @@ -1013,7 +1013,9 @@ function linear_sweep(
// spin = Rotate this many degrees around Z axis after anchor. Default: 0
// orient = Vector to rotate top toward after spin (module only)
// Named Anchors:
// "origin" = The native position of the shape.
// "origin" = The native position of the shape.
// "start-centroid" = (module only) When `angle<360`, the centroid of the shape, on the face at the starting face of the object
// "end-centroid" = (module only) When `angle<360`, the centroid of the shape, on the face at the ending face of the object
// Anchor Types:
// "hull" = Anchors to the virtual convex hull of the shape.
// "intersect" = Anchors to the surface of the shape.
Expand Down Expand Up @@ -1301,6 +1303,7 @@ function rotate_sweep(
spin=0, orient=UP, start=0,
_tex_inhibit_y_slicing
) =
assert(is_num(angle) && angle>0 && angle<=360,"\nangle must be a positive number not more than 360")
assert(num_defined([closed,caps])<2, "\nIn rotate_sweep the `closed` paramter has been replaced by `caps` with the opposite meaning. You cannot give both.")
assert(num_defined([tex_reps,tex_counts])<2, "\nIn rotate_sweep() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both.")
assert(num_defined([tex_scale,tex_depth])<2, "\nIn linear_sweep() the 'tex_scale' parameter has been replaced by 'tex_depth'. You cannot give both.")
Expand Down Expand Up @@ -1382,7 +1385,8 @@ module rotate_sweep(
_tex_inhibit_y_slicing=false
) {
dummy =
assert(num_defined([closed,caps])<2, "\nIn rotate_sweep the `closed` paramter has been replaced by `caps` with the opposite meaning. You cannot give both.")
assert(is_num(angle) && angle>0 && angle<=360,"\nangle must be a positive number not more than 360")
assert(num_defined([closed,caps])<2, "\nIn rotate_sweep the `closed` parameter has been replaced by `caps` with the opposite meaning. You cannot give both.")
assert(num_defined([tex_reps,tex_counts])<2, "\nIn rotate_sweep() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both.")
assert(num_defined([tex_scale,tex_depth])<2, "\nIn rotate_sweep() the 'tex_scale' parameter has been replaced by 'tex_depth'. You cannot give both.")
assert(!is_path(shape) || caps || len(shape)>=3, "\n'shape' is a path and caps=false, but a closed path requires three points.");
Expand All @@ -1393,7 +1397,15 @@ module rotate_sweep(
: tex_reps;
tex_depth = is_def(tex_scale)? echo("In rotate_sweep() the 'tex_scale' parameter is deprecated and has been replaced by 'tex_depth'")tex_scale
: default(tex_depth,1);
region = _force_xplus(force_region(shape));
region = is_path(shape) && caps ? _force_xplus([deduplicate([[0,shape[0].y], each shape, [0,last(shape).y]])])
: _force_xplus(force_region(shape));
ctr2d = centroid(region);
ctr3d = [ctr2d.x, 0, ctr2d.y];
namedanch = angle==360 ? []
:[
named_anchor("start-centroid", ctr3d, FWD),
named_anchor("end-centroid", rot = zrot(angle)*move(ctr3d)*xrot(-90)*zrot(180))
];
check = assert(is_region(region), "\nInput is not a region or polygon.");
bounds = pointlist_bounds(flatten(region));
min_x = bounds[0].x;
Expand All @@ -1420,25 +1432,24 @@ module rotate_sweep(
style=style,
atype=atype, anchor=anchor,
spin=spin, orient=orient, start=start
) children();
)
change_anchors(named=namedanch) children();
} else {
region = is_path(shape) && caps ? [deduplicate([[0,shape[0].y], each shape, [0,last(shape).y]])]
: region;
steps = ceil(segs(max_x) * angle / 360) + (angle<360? 1 : 0);
skmat = down(min_y) * skew(sxz=shift.x/h, syz=shift.y/h) * up(min_y);
transforms = [
if (angle==360) for (i=[0:1:steps-1]) skmat * rot([90,0,start+360-i*360/steps]),
if (angle<360) for (i=[0:1:steps-1]) skmat * rot([90,0,start+angle-i*angle/(steps-1)]),
];
sweep(
region, transforms,
closed=angle==360,
caps=angle!=360,
style=style, cp=cp,
convexity=convexity,
atype=atype, anchor=anchor,
spin=spin, orient=orient
) children();
sweep(region, transforms,
closed=angle==360,
caps=angle!=360,
style=style, cp=cp,
convexity=convexity,
atype=atype, anchor=anchor,
spin=spin, orient=orient)
change_anchors(named=namedanch)
children();
}
}

Expand Down Expand Up @@ -2698,8 +2709,8 @@ function sweep(shape, transforms, closed=false, caps, style="min_edge",
for (rgn=regions) each [
for (path=rgn)
sweep(path, transforms, closed=closed, caps=false, style=style),
if (flatcaps[0]) vnf_from_region(rgn, transform=transforms[0], reverse=true),
if (flatcaps[1]) vnf_from_region(rgn, transform=last(transforms)),
if (flatcaps[0]) vnf_from_region(rgn, transform=transforms[0], reverse=true, triangulate=true), // triangulation needed?
if (flatcaps[1]) vnf_from_region(rgn, transform=last(transforms), triangulate=true),
],
],
vnf = vnf_join(vnfs)
Expand Down Expand Up @@ -4752,7 +4763,6 @@ function _textured_revolution(
style="min_edge", atype="intersect",
anchor=CENTER, spin=0, orient=UP
) =
assert(angle>0 && angle<=360)
assert(is_path(shape,[2]) || is_region(shape))
assert(is_undef(samples) || is_int(samples))
assert(is_bool(closed))
Expand All @@ -4772,6 +4782,10 @@ function _textured_revolution(
testpoly = [[0,shape[0].y], each shape, [0,last(shape).y]]
)
[[is_polygon_clockwise(testpoly) ? shape : reverse(shape)]],




checks = [
for (rgn=regions, path=rgn)
assert(all(path, function(pt) pt.x>=0),"\nAll points in the shape must have non-negative x value."),
Expand Down
2 changes: 1 addition & 1 deletion utility.scad
Original file line number Diff line number Diff line change
Expand Up @@ -986,7 +986,7 @@ module assert_equal(got, expected, info) {
// Returns the differential geometry if they are not quite the same shape and size.
// Arguments:
// eps = The surface of the two shapes must be within this size of each other. Default: 1/1024
// Example:
// Example(NORENDER): (Example disabled because OpenSCAD bug prevents it from displaying)
// $fn=36;
// shape_compare() {
// sphere(d=100);
Expand Down