mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-10-03 21:31:53 +02:00
Merge pull request #1784 from adrianVmariano/master
path_sweep endcap anchors; change_anchors()
This commit is contained in:
@@ -3367,6 +3367,45 @@ function named_anchor(name, pos, orient, spin, rot, flip, info) =
|
|||||||
[name, pos, dir, spin, if (info) 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()
|
// Function: attach_geom()
|
||||||
// Synopsis: Returns the internal geometry description of an attachable object.
|
// Synopsis: Returns the internal geometry description of an attachable object.
|
||||||
// Topics: Attachments
|
// Topics: Attachments
|
||||||
|
38
skin.scad
38
skin.scad
@@ -1014,6 +1014,8 @@ function linear_sweep(
|
|||||||
// orient = Vector to rotate top toward after spin (module only)
|
// orient = Vector to rotate top toward after spin (module only)
|
||||||
// Named Anchors:
|
// 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:
|
// Anchor Types:
|
||||||
// "hull" = Anchors to the virtual convex hull of the shape.
|
// "hull" = Anchors to the virtual convex hull of the shape.
|
||||||
// "intersect" = Anchors to the surface of the shape.
|
// "intersect" = Anchors to the surface of the shape.
|
||||||
@@ -1301,6 +1303,7 @@ function rotate_sweep(
|
|||||||
spin=0, orient=UP, start=0,
|
spin=0, orient=UP, start=0,
|
||||||
_tex_inhibit_y_slicing
|
_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([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_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.")
|
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.")
|
||||||
@@ -1382,7 +1385,8 @@ module rotate_sweep(
|
|||||||
_tex_inhibit_y_slicing=false
|
_tex_inhibit_y_slicing=false
|
||||||
) {
|
) {
|
||||||
dummy =
|
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_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(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.");
|
assert(!is_path(shape) || caps || len(shape)>=3, "\n'shape' is a path and caps=false, but a closed path requires three points.");
|
||||||
@@ -1393,7 +1397,15 @@ module rotate_sweep(
|
|||||||
: tex_reps;
|
: 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
|
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);
|
: 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.");
|
check = assert(is_region(region), "\nInput is not a region or polygon.");
|
||||||
bounds = pointlist_bounds(flatten(region));
|
bounds = pointlist_bounds(flatten(region));
|
||||||
min_x = bounds[0].x;
|
min_x = bounds[0].x;
|
||||||
@@ -1420,25 +1432,24 @@ module rotate_sweep(
|
|||||||
style=style,
|
style=style,
|
||||||
atype=atype, anchor=anchor,
|
atype=atype, anchor=anchor,
|
||||||
spin=spin, orient=orient, start=start
|
spin=spin, orient=orient, start=start
|
||||||
) children();
|
)
|
||||||
|
change_anchors(named=namedanch) children();
|
||||||
} else {
|
} 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);
|
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);
|
skmat = down(min_y) * skew(sxz=shift.x/h, syz=shift.y/h) * up(min_y);
|
||||||
transforms = [
|
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+360-i*360/steps]),
|
||||||
if (angle<360) for (i=[0:1:steps-1]) skmat * rot([90,0,start+angle-i*angle/(steps-1)]),
|
if (angle<360) for (i=[0:1:steps-1]) skmat * rot([90,0,start+angle-i*angle/(steps-1)]),
|
||||||
];
|
];
|
||||||
sweep(
|
sweep(region, transforms,
|
||||||
region, transforms,
|
|
||||||
closed=angle==360,
|
closed=angle==360,
|
||||||
caps=angle!=360,
|
caps=angle!=360,
|
||||||
style=style, cp=cp,
|
style=style, cp=cp,
|
||||||
convexity=convexity,
|
convexity=convexity,
|
||||||
atype=atype, anchor=anchor,
|
atype=atype, anchor=anchor,
|
||||||
spin=spin, orient=orient
|
spin=spin, orient=orient)
|
||||||
) children();
|
change_anchors(named=namedanch)
|
||||||
|
children();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2698,8 +2709,8 @@ function sweep(shape, transforms, closed=false, caps, style="min_edge",
|
|||||||
for (rgn=regions) each [
|
for (rgn=regions) each [
|
||||||
for (path=rgn)
|
for (path=rgn)
|
||||||
sweep(path, transforms, closed=closed, caps=false, style=style),
|
sweep(path, transforms, closed=closed, caps=false, style=style),
|
||||||
if (flatcaps[0]) vnf_from_region(rgn, transform=transforms[0], reverse=true),
|
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)),
|
if (flatcaps[1]) vnf_from_region(rgn, transform=last(transforms), triangulate=true),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
vnf = vnf_join(vnfs)
|
vnf = vnf_join(vnfs)
|
||||||
@@ -4752,7 +4763,6 @@ function _textured_revolution(
|
|||||||
style="min_edge", atype="intersect",
|
style="min_edge", atype="intersect",
|
||||||
anchor=CENTER, spin=0, orient=UP
|
anchor=CENTER, spin=0, orient=UP
|
||||||
) =
|
) =
|
||||||
assert(angle>0 && angle<=360)
|
|
||||||
assert(is_path(shape,[2]) || is_region(shape))
|
assert(is_path(shape,[2]) || is_region(shape))
|
||||||
assert(is_undef(samples) || is_int(samples))
|
assert(is_undef(samples) || is_int(samples))
|
||||||
assert(is_bool(closed))
|
assert(is_bool(closed))
|
||||||
@@ -4772,6 +4782,10 @@ function _textured_revolution(
|
|||||||
testpoly = [[0,shape[0].y], each shape, [0,last(shape).y]]
|
testpoly = [[0,shape[0].y], each shape, [0,last(shape).y]]
|
||||||
)
|
)
|
||||||
[[is_polygon_clockwise(testpoly) ? shape : reverse(shape)]],
|
[[is_polygon_clockwise(testpoly) ? shape : reverse(shape)]],
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
checks = [
|
checks = [
|
||||||
for (rgn=regions, path=rgn)
|
for (rgn=regions, path=rgn)
|
||||||
assert(all(path, function(pt) pt.x>=0),"\nAll points in the shape must have non-negative x value."),
|
assert(all(path, function(pt) pt.x>=0),"\nAll points in the shape must have non-negative x value."),
|
||||||
|
@@ -986,7 +986,7 @@ module assert_equal(got, expected, info) {
|
|||||||
// Returns the differential geometry if they are not quite the same shape and size.
|
// Returns the differential geometry if they are not quite the same shape and size.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// eps = The surface of the two shapes must be within this size of each other. Default: 1/1024
|
// 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;
|
// $fn=36;
|
||||||
// shape_compare() {
|
// shape_compare() {
|
||||||
// sphere(d=100);
|
// sphere(d=100);
|
||||||
|
Reference in New Issue
Block a user