mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-08-12 21:14:17 +02:00
Merge pull request #1658 from adrianVmariano/master
rotate_sweep bugfix & change closed=false to caps=true
This commit is contained in:
@@ -501,7 +501,7 @@ function reverse(list) =
|
||||
// Description:
|
||||
// Rotates the contents of a list by `n` positions left, so that list[n] becomes the first entry of the list.
|
||||
// If `n` is negative, then the rotation is `abs(n)` positions to the right.
|
||||
// If `list` is a string, then a string is returned with the characters rotates within the string.
|
||||
// If `list` is a string, then a string is returned with the characters rotated within the string.
|
||||
// Arguments:
|
||||
// list = The list to rotate.
|
||||
// n = The number of positions to rotate by. If negative, rotated to the right. Positive rotates to the left. Default: 1
|
||||
|
@@ -1077,7 +1077,7 @@ function regular_prism(n,
|
||||
[0,height/2],
|
||||
]
|
||||
)
|
||||
rotate_sweep(path,closed=false,$fn=n)
|
||||
rotate_sweep(path,caps=true,$fn=n)
|
||||
: is_undef(texture) ? cylinder(h=height, r1=r1, r2=r2, center=true, $fn=n)
|
||||
: linear_sweep(regular_ngon(n=n,r=r1),scale=r2/r1,height=height,center=true,
|
||||
texture=texture, tex_reps=tex_reps, tex_size=tex_size,
|
||||
@@ -2366,7 +2366,7 @@ function cyl(
|
||||
texture=texture, tex_reps=tex_reps, tex_size=tex_size,
|
||||
tex_inset=tex_inset, tex_rot=tex_rot,
|
||||
tex_depth=tex_depth, tex_samples=tex_samples,
|
||||
tex_taper=tex_taper, style=style, closed=false,
|
||||
tex_taper=tex_taper, style=style, caps=true,
|
||||
_tex_inhibit_y_slicing=true
|
||||
),
|
||||
skmat = down(l/2) *
|
||||
|
134
skin.scad
134
skin.scad
@@ -896,10 +896,13 @@ function linear_sweep(
|
||||
// the sweep starts; set it to 180 to get the historical rotate_extrude() behavior.
|
||||
// .
|
||||
// The region or path that you provide to sweep is defined in the XY plane and cannot have any negative x values. By default a path is treated as a closed shape.
|
||||
// (Regions are always composed of closed polygons.) If you give a path and specify `closed=false` then the path will be connected to the Y axis by
|
||||
// a horizontal segment at each end, resulting in flat faces at the top and bottom. These flat faces do not receive any applied texture. No segment of of the
|
||||
// region---including the closing segments added to polygons---can lie on the Y axis. When `closed=false` you can terminate one or both ends of the path
|
||||
// on the Y axis if you want texturing to continue all the way to the center.
|
||||
// (Regions are always composed of closed polygons.) When you apply a texture, no path in your region can have more than one edge on the Y axis.
|
||||
// If you give a path whose endpoints are not on the Y axis and specify `caps=true` then the path
|
||||
// endpoints are connected to the Y axis by a horizontal segment at each end, and the corresponding top and bottom surfaces in the revolution do not receive texture.
|
||||
// You can terminate just one end of the path on the Y axis and in this case, you get a single untextured cap. If your texture is not zero at the
|
||||
// edges, the endcaps may appear textured: they will not be flat because the top perimeter will follow the texture. You can use the `tex_taper` parameter to
|
||||
// taper the texture to zero at the top and bottom and therefore produce flat caps. If taper is set to a percentage strictly between 0 and 50 it tapers
|
||||
// over that percentage of the path to zero at the end, resulting in flat faces at the top and bottom.
|
||||
// .
|
||||
// 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
|
||||
@@ -924,7 +927,7 @@ function linear_sweep(
|
||||
// tex_aspect = Choose the angle of the revolution to maintain this aspect ratio for the tiles. You must specify tex_reps. Overrides any angle specified.
|
||||
// pixel_aspect = Choose the angle of the revolution to maintain this apsect ratio for pixels in a heightfield texture. You must specify tex_reps. Overrides any angle specified.
|
||||
// style = {{vnf_vertex_array()}} style. Default: "min_edge"
|
||||
// closed = If false, and `shape` is a path, then the revolved path is connected to the axis of rotation with untextured caps. Ignored if `shape` is not a path. Default: `true`
|
||||
// caps = If true and `shape` is a path whose endpoints are to the right of the Y axis, then adds untextured caps to the top and/or bottom of the revolved surface. Ignored if `shape` is not a path or if its endpoints are on the Y axis. Default: `false`
|
||||
// convexity = (Module only) Convexity setting for use with polyhedron. Default: 10
|
||||
// cp = Centerpoint for determining "intersect" anchors or centering the shape. Determintes the base of the anchor vector. Can be "centroid", "mean", "box" or a 3D point. Default: "centroid"
|
||||
// atype = Select "hull" or "intersect" anchor types. Default: "hull"
|
||||
@@ -953,19 +956,19 @@ function linear_sweep(
|
||||
// path = right(50, p=circle(d=40));
|
||||
// rotate_sweep(path, texture="bricks_vnf",tex_size=10,
|
||||
// tex_depth=0.5, style="concave");
|
||||
// Example(NoAxes): The simplest way to create a cylinder with just a single line segment and `closed=false`. Note that all cylinder models will require `closed=false` because otherwise a closing line segment lies on the Y axis. With this cylinder, the top and bottom have no texture.
|
||||
// Example(NoAxes): The simplest way to create a cylinder with just a single line segment and `caps=true`. With this cylinder, the top and bottom have no texture.
|
||||
// rotate_sweep([[20,-10],[20,10]], texture="dots",
|
||||
// tex_reps=[6,2],closed=false);
|
||||
// Example(NoAxes): If we manually connect the top and bottom then they also receive texture. Note that `closed` is still false, but the caps have zero area.
|
||||
// tex_reps=[6,2],caps=true);
|
||||
// Example(NoAxes): If we manually connect the top and bottom then they also receive texture.
|
||||
// rotate_sweep([[0,-10],[20,-10],[20,10],[0,10]], texture="dots",
|
||||
// tex_reps=[6,6],closed=false,tex_depth=1.5);
|
||||
// tex_reps=[6,6],,tex_depth=1.5);
|
||||
// Example(NoAxes,VPR=[95.60,0.00,69.80],VPD=74.40,VPT=[5.81,5.74,1.97]): You can connect just the top or bottom alone instead of both to get texture on one and a flat cap on the other. Here you can see that the sloped top has texture but the bottom does not. Also note that the texture doesn't fit neatly on the side and top like it did in the previous two examples, but makes a somewhat ugly transition across the corner. You have to size your object carefully so that the tops and sides each fit an integer number of texture tiles to avoid this type of transition.
|
||||
// rotate_sweep([[15,-10],[15,10],[0,15]], texture="dots", tex_reps=[6,6],
|
||||
// angle=90,closed=false,tex_depth=1.5);
|
||||
// Example(NoAxes,VPR=[55.00,0.00,25.00],VPD=126.00,VPT=[1.37,0.06,-0.75]): Ribbed sphere. Must set `closed=false` because the arcs terminate on the Z axis.n
|
||||
// angle=90,caps=true,tex_depth=1.5);
|
||||
// Example(NoAxes,VPR=[55.00,0.00,25.00],VPD=126.00,VPT=[1.37,0.06,-0.75]): Ribbed sphere.
|
||||
// path = arc(r=20, $fn=64, angle=[-90, 90]);
|
||||
// rotate_sweep(path, 360, texture = texture("wave_ribs",n=15),
|
||||
// tex_size=[8,1.5],closed=false);
|
||||
// tex_size=[8,1.5]);
|
||||
// Example: For this model we use `closed=false` to create the flat, untextured caps.
|
||||
// tex = [
|
||||
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
@@ -983,7 +986,7 @@ function linear_sweep(
|
||||
// ];
|
||||
// path = arc(cp=[0,0], r=40, start=60, angle=-120);
|
||||
// rotate_sweep(
|
||||
// path, closed=false,
|
||||
// path, caps=true,
|
||||
// texture=tex, tex_size=[20,20],
|
||||
// tex_depth=1, style="concave");
|
||||
// Example:
|
||||
@@ -995,7 +998,7 @@ function linear_sweep(
|
||||
// ];
|
||||
// path = bezpath_curve(bezpath, splinesteps=32);
|
||||
// rotate_sweep(
|
||||
// path, closed=false,
|
||||
// path, caps=true,
|
||||
// texture="diamonds", tex_size=[10,10],
|
||||
// tex_depth=1, style="concave");
|
||||
// Example:
|
||||
@@ -1005,11 +1008,11 @@ function linear_sweep(
|
||||
// [20,-20], [20,-30],
|
||||
// ];
|
||||
// vnf = rotate_sweep(
|
||||
// path, closed=false,
|
||||
// path, caps=true,
|
||||
// texture="trunc_pyramids",
|
||||
// tex_size=[5,5], tex_depth=1,
|
||||
// style="convex");
|
||||
// vnf_polyhedron(vnf, convexity=10);
|
||||
// vnf_polyhedron(vnf, convexity=10); //!!!!!
|
||||
// Example:
|
||||
// rgn = [
|
||||
// right(40, p=circle(d=50)),
|
||||
@@ -1026,7 +1029,7 @@ function linear_sweep(
|
||||
// [20,-20], [20,-30],
|
||||
// ];
|
||||
// rotate_sweep(
|
||||
// path, closed=false,
|
||||
// path, caps=true,
|
||||
// texture="trunc_pyramids",
|
||||
// tex_size=[5,5], tex_depth=1,
|
||||
// tex_taper=20,
|
||||
@@ -1039,13 +1042,13 @@ function linear_sweep(
|
||||
// [20,-20], [20,-30],
|
||||
// ];
|
||||
// rotate_sweep(
|
||||
// path, closed=false,
|
||||
// path, caps=true,
|
||||
// texture="trunc_pyramids",
|
||||
// tex_size=[5,5], tex_depth=1,
|
||||
// tex_taper=[[0,0], [10,0], [10.1,1], [100,1]],
|
||||
// style="convex",
|
||||
// convexity=10);
|
||||
// Example(3D,NoAxes,Med,VPT=[-2.92656,1.26781,0.102897],VPR=[62.7,0,222.4],VPD=216.381): This VNF tile makes a closed shape and the actual main extrusion is not created.
|
||||
// Example(3D,NoAxes,Med,VPT=[-2.92656,1.26781,0.102897],VPR=[62.7,0,222.4],VPD=216.381): This VNF tile makes a closed shape and the actual main extrusion is not created. We give `caps=true` to prevent the shape from being closed on the outside, but because the VNF tile has no edges, no actual cap is created.
|
||||
// shape = skin([rect(2/5),
|
||||
// rect(2/3),
|
||||
// rect(2/5)],
|
||||
@@ -1054,7 +1057,7 @@ function linear_sweep(
|
||||
// caps=false);
|
||||
// tile = move([0,1/2,2/3],yrot(90,shape));
|
||||
// path = [for(y=[-30:30]) [ 20-3*(1-cos((y+30)/60*360)),y]];
|
||||
// rotate_sweep(path, closed=false, texture=tile,
|
||||
// rotate_sweep(path, caps=false, texture=tile,
|
||||
// tex_size=[10,10], tex_depth=5);
|
||||
// Example(3D,Med,VPT=[1.04269,4.35278,-0.716624],VPR=[98.4,0,43.9],VPD=175.268): Adding the angle parameter cuts off the extrusion. Note how each extruded component is capped.
|
||||
// shape = skin([rect(2/5),
|
||||
@@ -1065,7 +1068,7 @@ function linear_sweep(
|
||||
// caps=false);
|
||||
// tile = move([0,1/2,2/3],yrot(90,shape));
|
||||
// path = [for(y=[-30:30]) [ 20-3*(1-cos((y+30)/60*360)),y]];
|
||||
// rotate_sweep(path, closed=false, texture=tile,
|
||||
// rotate_sweep(path, caps=true, texture=tile,
|
||||
// tex_size=[10,15], tex_depth=5, angle=215);
|
||||
// Example(3D,NoAxes,Med,VPT=[1.00759,3.89216,-1.27032],VPR=[57.1,0,34.8],VPD=240.423): Turning the texture 90 degrees with `tex_rot` produces a texture that ends at the top and bottom.
|
||||
// shape = skin([rect(2/5),
|
||||
@@ -1076,7 +1079,7 @@ function linear_sweep(
|
||||
// caps=false);
|
||||
// tile = move([0,1/2,2/3],yrot(90,shape));
|
||||
// path = [for(y=[-30:30]) [ 20-3*(1-cos((y+30)/60*360)),y]];
|
||||
// rotate_sweep(path, closed=false, texture=tile, tex_rot=90,
|
||||
// rotate_sweep(path, caps=true, texture=tile, tex_rot=90,
|
||||
// tex_size=[12,8], tex_depth=9, angle=360);
|
||||
// Example(3D,Med,NoAxes,VPR=[78.1,0,199.3],VPT=[-4.55445,1.37814,-4.39897],VPD=192.044): A basket weave texture, here only halfway around the circle to avoid clutter.
|
||||
// diag_weave_vnf = [
|
||||
@@ -1097,7 +1100,7 @@ function linear_sweep(
|
||||
// ];
|
||||
// path = [for(y=[-30:30]) [ 20-3*(1-cos((y+30)/60*360)),y]];
|
||||
// down(31)linear_extrude(height=1)arc(r=23,angle=[0,180], wedge=true);
|
||||
// rotate_sweep(path, closed=false, texture=diag_weave_vnf, angle=180,
|
||||
// rotate_sweep(path, caps=true, texture=diag_weave_vnf, angle=180,
|
||||
// tex_size=[10,10], convexity=12, tex_depth=2);
|
||||
// Example(3D,VPR=[59.20,0.00,159.20],VPD=74.40,VPT=[7.45,6.83,1.54],NoAxes): Textures can be used to place images onto objects. If you want to place an image onto a cylinder you probably don't want it to cover the whole cylinder, or to create many small copies. To do this you can create a textured cylinder with an angle less than 360 degrees to hold the texture. In this example we calculate the angle so that the output has the same aspect ratio. The default `tex_extra` of zero for a single tile ensures that the image appears without an extra border.
|
||||
// img = [
|
||||
@@ -1118,8 +1121,7 @@ function linear_sweep(
|
||||
// r = 15;
|
||||
// ang = len(img[0])/len(img)*h/(2*PI*r)*360;
|
||||
// rotate_sweep([[r,-h/2],[r,h/2]], texture=img,
|
||||
// tex_reps=1,angle=ang, closed=false);
|
||||
//
|
||||
// tex_reps=1,angle=ang, caps=true);
|
||||
// Example(3D,VPR=[80.20,0.00,138.40],VPD=82.67,VPT=[6.88,7.29,1.77],NoAxes): Here we have combined the above model with a suitable cylinder. Note that with a coarse texture like this you need to either match the `$fn` of the cylinder to the texture, or choose a sufficiently fine cylinder to avoid conflicting facets.
|
||||
// img = [
|
||||
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
@@ -1139,7 +1141,7 @@ function linear_sweep(
|
||||
// r = 15;
|
||||
// ang = len(img[0])/len(img)*h/(2*PI*r)*360;
|
||||
// rotate_sweep([[r,-h/2],[r,h/2]], texture=img,
|
||||
// tex_reps=1,angle=ang, closed=false);
|
||||
// tex_reps=1,angle=ang, caps=true);
|
||||
// cyl(r=r,h=27,$fn=128);
|
||||
// Example(3D,VPR=[68.30,0.00,148.90],VPD=91.85,VPT=[-0.56,5.78,-0.90],NoAxes): Above we explicitly calculated the required angle to produce the correct aspect ratio. Here we use `pixel_aspect` which produces an output whose average width has the desired aspect ratio.
|
||||
// img = [
|
||||
@@ -1157,7 +1159,7 @@ function linear_sweep(
|
||||
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
// ];
|
||||
// rotate_sweep([[15,-10],[5,10]], texture=img,
|
||||
// tex_reps=[1,1], closed=false, pixel_aspect=1);
|
||||
// tex_reps=[1,1], caps=true, pixel_aspect=1);
|
||||
// cyl(r1=16,r2=4,h=24,$fn=128);
|
||||
// Example(3D,VPR=[96.30,0.00,133.50],VPD=54.24,VPT=[1.94,2.85,-0.47]): Here we apply the texture to a sphere using the automatic `pixel_aspect` to determine the angle. Note that using {{spheroid()}} with the circum option eliminates artifacts arising due to mimatched faceting.
|
||||
// img = [
|
||||
@@ -1176,7 +1178,7 @@ function linear_sweep(
|
||||
// ];
|
||||
// arc = arc(r=10, angle=[-44,44],n=100);
|
||||
// rotate_sweep(arc, texture=img, tex_reps=[1,1],
|
||||
// closed=false, pixel_aspect=1);
|
||||
// caps=true, pixel_aspect=1);
|
||||
// spheroid(10,$fn=64,circum=true);
|
||||
|
||||
|
||||
@@ -1186,16 +1188,21 @@ function rotate_sweep(
|
||||
texture, tex_size=[5,5], tex_counts, tex_reps,
|
||||
tex_inset=false, tex_rot=0,
|
||||
tex_scale, tex_depth, tex_samples, tex_aspect, pixel_aspect,
|
||||
tex_taper, shift=[0,0], closed=true,
|
||||
tex_taper, shift=[0,0], caps, closed,
|
||||
style="min_edge", cp="centroid",
|
||||
atype="hull", anchor="origin",
|
||||
spin=0, orient=UP, start=0,
|
||||
_tex_inhibit_y_slicing
|
||||
) =
|
||||
assert(num_defined([closed,caps])<2, "In 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, "In rotate_sweep() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both.")
|
||||
assert(num_defined([tex_scale,tex_depth])<2, "In linear_sweep() the 'tex_scale' parameter has been replaced by 'tex_depth'. You cannot give both.")
|
||||
assert(!is_path(shape) || !closed || len(path)>=3, "'shape' is a path and closed=true, but a closed path requires three points")
|
||||
let( tex_reps = is_def(tex_counts)? echo("In rotate_sweep() the 'tex_counts' parameter is deprecated and has been replaced by 'tex_reps'")tex_counts
|
||||
assert(!is_path(shape) || caps || len(path)>=3, "'shape' is a path and caps=false, but a closed path requires three points")
|
||||
let(
|
||||
caps = is_def(caps) ? caps
|
||||
: is_def(closed) ? !closed
|
||||
: false,
|
||||
tex_reps = is_def(tex_counts)? echo("In rotate_sweep() the 'tex_counts' parameter is deprecated and has been replaced by 'tex_reps'")tex_counts
|
||||
: 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),
|
||||
@@ -1223,14 +1230,14 @@ function rotate_sweep(
|
||||
inhibit_y_slicing=_tex_inhibit_y_slicing,
|
||||
taper=tex_taper, tex_aspect=tex_aspect, pixel_aspect=pixel_aspect,
|
||||
shift=shift,
|
||||
closed=closed,
|
||||
closed=!caps,
|
||||
angle=angle,
|
||||
style=style,
|
||||
start=start
|
||||
) :
|
||||
let(
|
||||
region = !is_path(shape) || closed ? region
|
||||
: [deduplicate([[0,shape[0].y], each shape, [0,last(shape).y]])],
|
||||
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 = [
|
||||
@@ -1255,7 +1262,7 @@ module rotate_sweep(
|
||||
tex_scale, tex_depth, tex_samples,
|
||||
tex_taper, shift=[0,0],
|
||||
style="min_edge",
|
||||
closed=true, tex_extra, tex_aspect, pixel_aspect,
|
||||
caps, closed, tex_extra, tex_aspect, pixel_aspect,
|
||||
cp="centroid",
|
||||
convexity=10,
|
||||
atype="hull",
|
||||
@@ -1265,9 +1272,13 @@ module rotate_sweep(
|
||||
_tex_inhibit_y_slicing=false
|
||||
) {
|
||||
dummy =
|
||||
assert(num_defined([closed,caps])<2, "In 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, "In rotate_sweep() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both.")
|
||||
assert(num_defined([tex_scale,tex_depth])<2, "In rotate_sweep() the 'tex_scale' parameter has been replaced by 'tex_depth'. You cannot give both.")
|
||||
assert(!is_path(shape) || !closed || len(shape)>=3, "'shape' is a path and closed=true, but a closed path requires three points");
|
||||
assert(!is_path(shape) || caps || len(shape)>=3, "'shape' is a path and caps=false, but a closed path requires three points");
|
||||
caps = is_def(caps) ? caps
|
||||
: is_def(closed) ? !closed
|
||||
: false;
|
||||
tex_reps = is_def(tex_counts)? echo("In rotate_sweep() the 'tex_counts' parameter is deprecated and has been replaced by 'tex_reps'")tex_counts
|
||||
: 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
|
||||
@@ -1293,7 +1304,7 @@ module rotate_sweep(
|
||||
samples=tex_samples,
|
||||
taper=tex_taper,
|
||||
shift=shift,tex_extra=tex_extra,tex_aspect=tex_aspect, pixel_aspect=pixel_aspect,
|
||||
closed=closed,
|
||||
closed=!caps,
|
||||
inhibit_y_slicing=_tex_inhibit_y_slicing,
|
||||
angle=angle,
|
||||
style=style,
|
||||
@@ -1301,8 +1312,8 @@ module rotate_sweep(
|
||||
spin=spin, orient=orient, start=start
|
||||
) children();
|
||||
} else {
|
||||
region = !is_path(shape) || closed ? region
|
||||
: [deduplicate([[0,shape[0].y], each shape, [0,last(shape).y]])];
|
||||
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 = [
|
||||
@@ -4560,9 +4571,9 @@ function _textured_revolution(
|
||||
checks = [
|
||||
for (rgn=regions, path=rgn)
|
||||
assert(all(path, function(pt) pt.x>=0),"All points in the shape must have non-negative x value"),
|
||||
for(reg=regions, path=reg, edge=pair(path,wrap=closed))
|
||||
assert(edge[0].x>0 || edge[1].x>0,
|
||||
str("The shape cannot have any edges on the axis of rotation",closed?" (including the segment that closes the shape)":""))
|
||||
//for(reg=regions, path=reg, edge=pair(path,wrap=closed))
|
||||
// assert(edge[0].x>0 || edge[1].x>0,
|
||||
// str("The shape cannot have any edges on the axis of rotation",closed?" (including the segment that closes the shape)":""))
|
||||
]
|
||||
)
|
||||
assert(closed || is_path(shape,2), "closed=false is only allowed with paths")
|
||||
@@ -4570,10 +4581,11 @@ function _textured_revolution(
|
||||
counts = is_undef(counts) ? undef : force_list(counts,2),
|
||||
tex_size = force_list(tex_size,2),
|
||||
texture = _get_texture(texture, rot),
|
||||
tex_extra = is_vnf(texture) ? [1,1]
|
||||
: is_def(tex_extra) ? force_list(tex_extra,2)
|
||||
: counts==[1,1] ? [0,0]
|
||||
: [1,1],
|
||||
tex_extra_try = is_vnf(texture) ? [1,1]
|
||||
: is_def(tex_extra) ? force_list(tex_extra,2)
|
||||
: counts==[1,1] ? [0,0]
|
||||
: [1,1],
|
||||
tex_extra = angle==360 ? [1,tex_extra_try.y] : tex_extra_try,
|
||||
dummy = assert(is_def(counts) || num_defined([pixel_aspect,tex_aspect])==0, "Must specify tex_counts (not tex_size) when using pixel_aspect or tex_aspect")
|
||||
assert(is_undef(pixel_aspect) || !is_vnf(texture), "Cannot give pixel aspect with a VNF texture")
|
||||
assert(is_undef(samples) || is_vnf(texture), "You gave the tex_samples argument with a heightfield texture, which is not permitted. Use the n= argument to texture() instead"),
|
||||
@@ -4631,6 +4643,19 @@ function _textured_revolution(
|
||||
taperout = [[-1,retaper[0][1]], each retaper, [2,last(retaper)[1]]]
|
||||
) taperout :
|
||||
assert(false, "Bad taper= argument value."),
|
||||
|
||||
// Checks a path to see if it has segments on the Y axis. More than 1 is an error. If no segments return
|
||||
// path unchanged with closed=true. If there is 1 segment, delete that segment (by rotating the path so it's
|
||||
// at the end) and return closed=false. This prevents textures from continuing into the inside of a shape.
|
||||
open_axis_paths = function(path,closed)
|
||||
!closed ? [path,closed]
|
||||
: let(
|
||||
axind = [for(i=[0:1:len(path)-1]) if (approx(path[i].x,0) && approx(select(path,i+1).x,0)) i],
|
||||
dummy = assert(len(axind)<=1, "Found path with more than 1 segment on the Y axis, which is not supported with texturing.")
|
||||
)
|
||||
len(axind)==0 ? [path,true]
|
||||
:
|
||||
[list_rotate(path, (axind[0]+1)%len(path)), false],
|
||||
transform_point = function(tileind, tilez, counts_y, bases, norms)
|
||||
let(
|
||||
part = tileind * samples,
|
||||
@@ -4647,6 +4672,9 @@ function _textured_revolution(
|
||||
for (rgn = regions) let(
|
||||
rgn_wall_vnf = vnf_join(
|
||||
[for (path = rgn) let(
|
||||
path_closed = open_axis_paths(path,closed),
|
||||
path = path_closed[0],
|
||||
closed = path_closed[1],
|
||||
plen = path_length(path, closed=closed),
|
||||
counts_y = is_def(counts) ? counts.y : max(1,round(plen/tex_size.y)),
|
||||
obases = resample_path(path, n=counts_y * samples + (closed?0:tex_extra.y), closed=closed),
|
||||
@@ -4704,6 +4732,9 @@ function _textured_revolution(
|
||||
cap_rgn = side_open_path == [] ? []
|
||||
: [ for (path = rgn)
|
||||
let(
|
||||
path_closed = open_axis_paths(path,closed),
|
||||
path = path_closed[0],
|
||||
closed = path_closed[1],
|
||||
plen = path_length(path, closed=closed),
|
||||
counts_y = is_def(counts) ? counts.y : max(1,round(plen/tex_size.y)),
|
||||
bases = resample_path(path, n=counts_y * samples + (closed?0:tex_extra.y), closed=closed),
|
||||
@@ -4737,6 +4768,10 @@ function _textured_revolution(
|
||||
: [for(i=[0,1]) vnf_from_region(column(cap_rgn,i), rot([90,0,i*angle]), reverse=i==1)],
|
||||
extra_paths = side_closed_paths==[] ? []
|
||||
: [for (path = rgn) let(
|
||||
path_closed = open_axis_paths(path,closed),
|
||||
path = path_closed[0],
|
||||
closed = path_closed[1],
|
||||
|
||||
plen = path_length(path, closed=closed),
|
||||
counts_y = is_def(counts) ? counts.y : max(1,round(plen/tex_size.y)),
|
||||
bases = resample_path(path, n=counts_y * samples + (closed?0:1), closed=closed),
|
||||
@@ -4755,9 +4790,12 @@ function _textured_revolution(
|
||||
) vnf_join(concat(cap_vnfs, extra_vnfs)),
|
||||
endcaps_vnf = closed? EMPTY_VNF :
|
||||
let(
|
||||
plen = path_length(rgn[0], closed=closed),
|
||||
path_closed = open_axis_paths(rgn[0],closed),
|
||||
path = path_closed[0],
|
||||
closed = path_closed[1],
|
||||
plen = path_length(path, closed=closed),
|
||||
counts_y = is_def(counts) ? counts.y : max(1,round(plen/tex_size.y)),
|
||||
obases = resample_path(rgn[0], n=counts_y * samples + (closed?0:1), closed=closed),
|
||||
obases = resample_path(path, n=counts_y * samples + (closed?0:1), closed=closed),
|
||||
onorms = path_normals(obases, closed=closed),
|
||||
bases = xrot(90, p=path3d(obases)),
|
||||
norms = xrot(90, p=path3d(onorms)),
|
||||
|
Reference in New Issue
Block a user