mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-01 09:49:45 +00:00
Added extrude_2d_shapes_along_3dpath()
This commit is contained in:
parent
f1fc493120
commit
4c935bf9f2
2 changed files with 92 additions and 46 deletions
86
beziers.scad
86
beziers.scad
|
@ -45,7 +45,6 @@ function bez_point(curve,u)=
|
||||||
u
|
u
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Takes an array of bezier points and converts it into a 3D polyline.
|
// Takes an array of bezier points and converts it into a 3D polyline.
|
||||||
function bezier_polyline(bezier, splinesteps=16, N=3) = concat(
|
function bezier_polyline(bezier, splinesteps=16, N=3) = concat(
|
||||||
[
|
[
|
||||||
|
@ -121,11 +120,32 @@ module revolve_bezier(bezier, splinesteps=16, N=3, convexity=10, angle=360) {
|
||||||
xrot(180) zrot(-90) bezier_polygon(bezier, splinesteps, N);
|
xrot(180) zrot(-90) bezier_polygon(bezier, splinesteps, N);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Takes a closed 2D bezier and rotates it around the Z axis, forming a solid.
|
||||||
|
// Behaves like rotate_extrude(), except for beziers instead of shapes.
|
||||||
|
// bezier = array of 2D points for the bezier path to rotate.
|
||||||
|
// splinesteps = number of segments to divide each bezier segment into. default=16
|
||||||
|
// N = number of points in each bezier segment. default=3 (cubic)
|
||||||
|
// convexity = max number of walls a line could pass through, for preview. default=10
|
||||||
|
// angle = degrees of sweep to make. default=360
|
||||||
|
// Example:
|
||||||
|
// path = [
|
||||||
|
// [ 0, 10], [ 50, 0], [ 50, 40],
|
||||||
|
// [ 95, 40], [100, 40], [100, 45],
|
||||||
|
// [ 95, 45], [ 66, 45], [ 0, 20],
|
||||||
|
// [ 0, 12], [ 0, 12], [ 0, 10],
|
||||||
|
// [ 0, 10]
|
||||||
|
// ];
|
||||||
|
// rotate_extrude_bezier(path, splinesteps=32, $fn=180);
|
||||||
module rotate_extrude_bezier(bezier, splinesteps=16, N=3, convexity=10, angle=360) {
|
module rotate_extrude_bezier(bezier, splinesteps=16, N=3, convexity=10, angle=360) {
|
||||||
revolve_bezier(bezier, splinesteps=splinesteps, N=N, convexity=convexity, angle=angle);
|
rotate_extrude(convexity=convexity, angle=angle) {
|
||||||
|
bezier_polygon(bezier, splinesteps, N);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Takes a 2D bezier path and closes it to the X axis.
|
// Takes a 2D bezier path and closes it to the X axis.
|
||||||
function bezier_close_to_axis(bezier, N=3) =
|
function bezier_close_to_axis(bezier, N=3) =
|
||||||
let(
|
let(
|
||||||
|
@ -186,48 +206,10 @@ module revolve_bezier_offset_shell(bezier, offset=1, splinesteps=16, N=3, convex
|
||||||
// splinesteps = number of segments to divide each bezier segment into. default=16
|
// splinesteps = number of segments to divide each bezier segment into. default=16
|
||||||
// Example:
|
// Example:
|
||||||
// path = [ [0, 0, 0], [33, 33, 33], [66, -33, -33], [100, 0, 0] ];
|
// path = [ [0, 0, 0], [33, 33, 33], [66, -33, -33], [100, 0, 0] ];
|
||||||
// extrude_2d_shapes_along_bezier(path, splinesteps=32)
|
// extrude_2d_shapes_along_bezier(path) circle(r=10, center=true);
|
||||||
// circle(r=10, center=true);
|
module extrude_2d_shapes_along_bezier(bezier, splinesteps=16, N=3, convexity=10, clipsize=1000) {
|
||||||
module extrude_2d_shapes_along_bezier(bezier, splinesteps=16, N=3) {
|
path = slice(bezier_polyline(bezier, splinesteps, N), 0, -1);
|
||||||
pointslist = slice(bezier_polyline(bezier, splinesteps, N), 0, -1);
|
extrude_2d_shapes_along_3dpath(path, convexity=convexity, clipsize=clipsize) children();
|
||||||
ptcount = len(pointslist);
|
|
||||||
for (i = [0 : ptcount-2]) {
|
|
||||||
pt1 = pointslist[i];
|
|
||||||
pt2 = pointslist[i+1];
|
|
||||||
pt0 = i==0? pt1 : pointslist[i-1];
|
|
||||||
pt3 = (i>=ptcount-2)? pt2 : pointslist[i+2];
|
|
||||||
dist = distance(pt1,pt2);
|
|
||||||
v1 = pt2-pt1;
|
|
||||||
v0 = (i==0)? v1 : (pt1-pt0);
|
|
||||||
v2 = (i==ptcount-2)? v1 : (pt3-pt2);
|
|
||||||
az1 = atan2(v1[1], v1[0]);
|
|
||||||
alt1 = (len(pt1)<3)? 0 : atan2(v1[2], hypot(v1[1], v1[0]));
|
|
||||||
az0 = atan2(v0[1], v0[0]);
|
|
||||||
alt0 = (len(pt0)<3)? 0 : atan2(v0[2], hypot(v0[1], v0[0]));
|
|
||||||
az2 = atan2(v2[1], v2[0]);
|
|
||||||
alt2 = (len(pt2)<3)? 0 : atan2(v2[2], hypot(v2[1], v2[0]));
|
|
||||||
translate(pt1) {
|
|
||||||
difference() {
|
|
||||||
rotate([0, 90-alt1, az1]) {
|
|
||||||
translate([0, 0, -1]) {
|
|
||||||
linear_extrude(height=dist*3, convexity=10) {
|
|
||||||
children();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rotate([0, 90-(alt0+alt1)/2, (az0+az1)/2]) {
|
|
||||||
translate([0, 0, -dist-0.05]) {
|
|
||||||
cube(size=[99,99,dist*2], center=true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rotate([0, 90-(alt1+alt2)/2, (az1+az2)/2]) {
|
|
||||||
translate([0, 0, dist+dist]) {
|
|
||||||
cube(size=[99,99,dist*2], center=true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -240,7 +222,13 @@ module extrude_2d_shapes_along_bezier(bezier, splinesteps=16, N=3) {
|
||||||
// bezN = number of points in each extruded bezier segment. default=3 (cubic)
|
// bezN = number of points in each extruded bezier segment. default=3 (cubic)
|
||||||
// pathN = number of points in each path bezier segment. default=3 (cubic)
|
// pathN = number of points in each path bezier segment. default=3 (cubic)
|
||||||
// Example:
|
// Example:
|
||||||
// bez = [ [-15, 0], [25, -15], [-5, 10], [0, 10], [5, 10], [10, 5], [15, 0], [10, -5], [5, -10], [0, -10], [-5, -10], [-10, -5], [-15, 0] ];
|
// bez = [
|
||||||
|
// [-10, 0], [-15, -5],
|
||||||
|
// [ -5, -10], [ 0, -10], [ 5, -10],
|
||||||
|
// [ 10, -5], [ 15, 0], [10, 5],
|
||||||
|
// [ 5, 10], [ 0, 10], [-5, 10],
|
||||||
|
// [ 25, -15], [-10, 0]
|
||||||
|
// ];
|
||||||
// path = [ [0, 0, 0], [33, 33, 33], [66, -33, -33], [100, 0, 0] ];
|
// path = [ [0, 0, 0], [33, 33, 33], [66, -33, -33], [100, 0, 0] ];
|
||||||
// extrude_bezier_along_bezier(bez, path, pathsteps=64, bezsteps=32);
|
// extrude_bezier_along_bezier(bez, path, pathsteps=64, bezsteps=32);
|
||||||
module extrude_bezier_along_bezier(bezier, path, pathsteps=16, bezsteps=16, bezN=3, pathN=3) {
|
module extrude_bezier_along_bezier(bezier, path, pathsteps=16, bezsteps=16, bezN=3, pathN=3) {
|
||||||
|
@ -262,7 +250,13 @@ module extrude_bezier_along_bezier(bezier, path, pathsteps=16, bezsteps=16, bezN
|
||||||
// scale = relative size of top of extrusion to the bottom. default=1.0
|
// scale = relative size of top of extrusion to the bottom. default=1.0
|
||||||
// slices = number of vertical slices to use for twisted extrusion. default=20
|
// slices = number of vertical slices to use for twisted extrusion. default=20
|
||||||
// Example:
|
// Example:
|
||||||
// bez = [ [-15, 0], [25, -15], [-5, 10], [0, 10], [5, 10], [10, 5], [15, 0], [10, -5], [5, -10], [0, -10], [-5, -10], [-10, -5], [-15, 0] ];
|
// bez = [
|
||||||
|
// [-10, 0], [-15, -5],
|
||||||
|
// [ -5, -10], [ 0, -10], [ 5, -10],
|
||||||
|
// [ 10, -5], [ 15, 0], [10, 5],
|
||||||
|
// [ 5, 10], [ 0, 10], [-5, 10],
|
||||||
|
// [ 25, -15], [-10, 0]
|
||||||
|
// ];
|
||||||
// linear_extrude_bezier(bez, splinesteps=32, );
|
// linear_extrude_bezier(bez, splinesteps=32, );
|
||||||
module linear_extrude_bezier(bezier, height=100, splinesteps=16, N=3, center=true, convexity=10, twist=0, slices=20, scale=1.0) {
|
module linear_extrude_bezier(bezier, height=100, splinesteps=16, N=3, center=true, convexity=10, twist=0, slices=20, scale=1.0) {
|
||||||
linear_extrude(height=height, center=center, convexity=convexity, twist=twist, slices=slices, scale=scale) {
|
linear_extrude(height=height, center=center, convexity=convexity, twist=twist, slices=slices, scale=scale) {
|
||||||
|
|
52
paths.scad
52
paths.scad
|
@ -31,6 +31,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
include <transforms.scad>
|
||||||
include <math.scad>
|
include <math.scad>
|
||||||
include <quaternions.scad>
|
include <quaternions.scad>
|
||||||
include <triangulation.scad>
|
include <triangulation.scad>
|
||||||
|
@ -223,5 +224,56 @@ module extrude_2dpath_along_3dpath(polyline, path, convexity=10) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Extrudes 2D children along a 3D polyline path.
|
||||||
|
// path = array of points for the bezier path to extrude along.
|
||||||
|
// convexity = maximum number of walls a ran can pass through.
|
||||||
|
// clipsize = increase if artifacts are left. Default: 1000
|
||||||
|
// Example:
|
||||||
|
// path = [ [0, 0, 0], [33, 33, 33], [66, 33, 40], [100, 0, 0] ];
|
||||||
|
// extrude_2d_shapes_along_3dpath(path) circle(r=10, center=true);
|
||||||
|
module extrude_2d_shapes_along_3dpath(path, convexity=10, clipsize=1000) {
|
||||||
|
ptcount = len(path);
|
||||||
|
for (i = [0 : ptcount-2]) {
|
||||||
|
pt1 = path[i];
|
||||||
|
pt2 = path[i+1];
|
||||||
|
pt0 = i==0? pt1 : path[i-1];
|
||||||
|
pt3 = (i>=ptcount-2)? pt2 : path[i+2];
|
||||||
|
dist = distance(pt1,pt2);
|
||||||
|
v1 = pt2-pt1;
|
||||||
|
v0 = (i==0)? v1 : (pt1-pt0);
|
||||||
|
v2 = (i==ptcount-2)? v1 : (pt3-pt2);
|
||||||
|
az1 = atan2(v1[1], v1[0]);
|
||||||
|
alt1 = (len(pt1)<3)? 0 : atan2(v1[2], hypot(v1[1], v1[0]));
|
||||||
|
az0 = atan2(v0[1], v0[0]);
|
||||||
|
alt0 = (len(pt0)<3)? 0 : atan2(v0[2], hypot(v0[1], v0[0]));
|
||||||
|
az2 = atan2(v2[1], v2[0]);
|
||||||
|
alt2 = (len(pt2)<3)? 0 : atan2(v2[2], hypot(v2[1], v2[0]));
|
||||||
|
translate(pt1) {
|
||||||
|
difference() {
|
||||||
|
rotate([0, 90-alt1, az1]) {
|
||||||
|
down(dist) {
|
||||||
|
linear_extrude(height=dist*3, convexity=10) {
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rotate([0, 90-(alt0+alt1)/2, (az0+az1)/2]) {
|
||||||
|
down(dist+0.05) {
|
||||||
|
cube(size=[clipsize,clipsize,dist*2], center=true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
translate(v1) {
|
||||||
|
rotate([0, 90-(alt1+alt2)/2, (az1+az2)/2]) {
|
||||||
|
up(dist) {
|
||||||
|
cube(size=[clipsize,clipsize,dist*2], center=true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
||||||
|
|
Loading…
Reference in a new issue