mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-08-15 10:05:52 +02:00
add vnf_vertex_array() module
texture code cleanup doc fixes
This commit is contained in:
@@ -3475,6 +3475,35 @@ Access to the derivative smoothing parameter?
|
||||
// attach(RIGHT,"root")
|
||||
// join_prism(circle(r=8,$fn=32),
|
||||
// l=10, base="plane", fillet=4);
|
||||
// Example(3D,NoScales,VPR=[47.3,0,14.5],VPT=[-2.8467,-2.05938,-10.6999],VPD=220): Two join_prism objects are placed on the parent cylinder using anchors, and then their descriptions are used to contruct a curved handle with a bezier.
|
||||
// $fs=.5; $fa=4;
|
||||
// vspace=25;
|
||||
// bezlen=40;
|
||||
// cylr=20;
|
||||
// straightlen=10;
|
||||
// circ = circle(r=6);
|
||||
// cyl(r=cylr,h=50, rounding=3)
|
||||
// let(cyl=parent())
|
||||
// down(vspace/2)
|
||||
// attach(RIGHT+FWD, "root", spin=90)
|
||||
// join_prism(circ, base="cyl", base_r=20, height=straightlen, fillet=4)
|
||||
// let(base1=parent())
|
||||
// restore(cyl)
|
||||
// up(vspace/2)
|
||||
// attach(LEFT+FWD, "root", spin=90)
|
||||
// join_prism(circ, base="cyl", base_r=20, height=straightlen, fillet=4)
|
||||
// let(base2=parent())
|
||||
// let(
|
||||
// avg_dir = desc_dir(base1,anchor=TOP)+desc_dir(base2,anchor=TOP),
|
||||
// bez=[
|
||||
// desc_point(base1,anchor=TOP),
|
||||
// desc_point(base1,anchor=TOP)+bezlen*desc_dir(base1,anchor=TOP),
|
||||
// (cylr+straightlen+bezlen)*avg_dir,
|
||||
// desc_point(base2,anchor=TOP)+bezlen*desc_dir(base2,anchor=TOP),
|
||||
// desc_point(base2,anchor=TOP)]
|
||||
// )
|
||||
// path_sweep(circ,bezier_curve(bez,40));
|
||||
|
||||
module join_prism(polygon, base, base_r, base_d, base_T=IDENT,
|
||||
scale=1, prism_end_T=IDENT, short=false,
|
||||
length, l, height, h,
|
||||
@@ -4045,6 +4074,9 @@ function _prism_fillet_prism(name, basepoly, bot, top, d, k, N, overlap, uniform
|
||||
// n = number of facets to use for the fillets. Default: 15
|
||||
// n1 = number of facets at object1
|
||||
// n2 = number of facets at object2
|
||||
// fillet = fillet for both ends of the prism. Default: 0
|
||||
// fillet1 = fillet for the joint at object1
|
||||
// fillet2 = fillet for the joint at object2
|
||||
// k = fillet curvature parameter for both ends. Default: 0.7
|
||||
// k1 = fillet curvature parameter at object1
|
||||
// k2 = fillet curvature parameter at object2
|
||||
@@ -4513,8 +4545,8 @@ module prism_connector(profile, desc1, anchor1, desc2, anchor2, shift1=0, shift2
|
||||
smooth_normals, smooth_normals1, smooth_normals2,
|
||||
debug=false, debug_pos=false)
|
||||
{
|
||||
base_fillet = default(fillet1,fillet);
|
||||
aux_fillet = default(fillet2,fillet);
|
||||
base_fillet = first_defined([fillet1,fillet,0]);
|
||||
aux_fillet = first_defined([fillet2,fillet,0]);
|
||||
|
||||
base_overlap = first_defined([overlap1,overlap,1]);
|
||||
aux_overlap = first_defined([overlap2,overlap,1]);
|
||||
|
@@ -1218,12 +1218,12 @@ function regular_prism(n,
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
// Example(3D,NoScale,VPT=[-0.257402,0.467403,-0.648606],VPR=[46.6,0,16.6],VPD=29.2405): Basic textured tile
|
||||
// Example(3D,NoScales,VPT=[-0.257402,0.467403,-0.648606],VPR=[46.6,0,16.6],VPD=29.2405): Basic textured tile
|
||||
// textured_tile("trunc_diamonds", 10, tex_reps=[5,5]);
|
||||
// Example(3D,NoScale,VPT=[-0.0852782,0.259593,0.139667],VPR=[58.5,0,345.1],VPD=36.0994): Attaching a tile to a cube
|
||||
// Example(3D,NoAxes,VPT=[-0.0852782,0.259593,0.139667],VPR=[58.5,0,345.1],VPD=36.0994): Attaching a tile to a cube
|
||||
// cuboid([12,12,4]) attach(TOP,BOT)
|
||||
// textured_tile("trunc_pyramids", 10, tex_reps=[5,5], style="convex");
|
||||
// Example(3D,NoScale,VPT = [-0.0788193, 0.10015, -0.0938629], VPR = [57.8, 0, 34.1], VPD = 29.2405): This inset texture doesn't look obviously different, but you can see that the object is below the XY plane.
|
||||
// Example(3D,NoScales,VPT = [-0.0788193, 0.10015, -0.0938629], VPR = [57.8, 0, 34.1], VPD = 29.2405): This inset texture doesn't look obviously different, but you can see that the object is below the XY plane.
|
||||
// textured_tile("trunc_pyramids_vnf", 10, tex_reps=[5,5], tex_inset=true);
|
||||
// Example(3D,NoAxes,VPT=[0.242444,0.170054,-0.0714754],VPR=[67.6,0,33.4],VPD=36.0994): Here we use the `diff` option combined with {{diff()}} to attach the inset texture to the front of a parent cuboid.
|
||||
// diff()
|
||||
@@ -1233,17 +1233,17 @@ function regular_prism(n,
|
||||
// Example(3D,NoAxes,VPT=[5.86588,-0.107082,-0.311155],VPR=[17.2,0,9.6],VPD=32.4895): Tile shaped like a rhombic prism
|
||||
// textured_tile("ribs", w1=10, w2=10, shift=4,ysize=7);
|
||||
// Example(3D,NoAxes,VPT=[-0.487417,-0.398897,-0.143258],VPR=[10.2,0,12.4],VPD=26.3165): A tile shaped like a trapezoidal prism. Note that trapezoidal tiles will always distort the texture, resulting in curves
|
||||
// textured_tile("diamonds", w1=10, w2=7, ysize=7) show_anchors(2);
|
||||
// textured_tile("diamonds", w1=10, w2=7, ysize=7);
|
||||
// Example(3D,NoAxes,VPT=[-0.0889877,-0.31974,0.554444],VPR=[22.1,0,22.2],VPD=32.4895): An inset trapezoidal tile placed into a cube
|
||||
// diff()cuboid([10,10,2])
|
||||
// attach(TOP,BOT)
|
||||
// textured_tile("trunc_diamonds", tex_reps=[5,5], tex_inset=true,
|
||||
// w1=8, w2=4, ysize=8, diff=true);
|
||||
// Example(3D,NoScales,VPT=[-0.0889877,-0.31974,0.554444],VPR=[58.5,0,21.5],VPD=32.4895): This example shows what happens if you set `extra` to zero for the "pyramids" texture. Note that the texture doesn't finish. The default of `extra=1` produces the correct result.
|
||||
// Example(3D,NoAxes,VPT=[-0.0889877,-0.31974,0.554444],VPR=[58.5,0,21.5],VPD=32.4895): This example shows what happens if you set `extra` to zero for the "pyramids" texture. Note that the texture doesn't finish. The default of `extra=1` produces the correct result.
|
||||
// textured_tile("pyramids", 10, tex_reps=[5,5], extra=0);
|
||||
// Example(3D,NoScales,VPT=[-0.212176,-0.651766,0.124004],VPR=[58.5,0,21.5],VPD=29.2405): This texture has an asymmetry even with the default `extra=1`.
|
||||
// textured_tile("trunc_ribs", 10, tex_reps=[5,2]);
|
||||
// Example(3D,NoScales,VPT=[-0.212176,-0.651766,0.124004],VPR=[58.5,0,21.5],VPD=29.2405): It could be fixed by setting `extra=2`, which would place an extra flat strip on the right. But another option is to use the `skip` parameter to trim the flat part from the left. Note that we are also skipping in the y direction, but it doesn't make a difference for this texture, except that you need to have enough texture tiles to accommodate the skip. You can also set `skip` to a vector.
|
||||
// Example(3D,NoAxes,VPT=[-0.212176,-0.651766,0.124004],VPR=[58.5,0,21.5],VPD=29.2405): This texture has an asymmetry even with the default `extra=1`.
|
||||
// textured_tile("trunc_ribs", 10, tex_reps=[5,1]);
|
||||
// Example(3D,NoAxes,VPT=[-0.212176,-0.651766,0.124004],VPR=[58.5,0,21.5],VPD=29.2405): It could be fixed by setting `extra=2`, which would place an extra flat strip on the right. But another option is to use the `skip` parameter to trim the flat part from the left. Note that we are also skipping in the y direction, but it doesn't make a difference for this texture, except that you need to have enough texture tiles to accommodate the skip, so we increased the Y reps value to 2. You can also set `skip` to a vector.
|
||||
// textured_tile("trunc_ribs", 10, tex_reps=[5,2], skip=1);
|
||||
|
||||
|
||||
|
156
skin.scad
156
skin.scad
@@ -651,7 +651,7 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close
|
||||
// linear_sweep(path, texture=tex, tex_size=[5,5], h=40);
|
||||
// Example: Textured with twist and scale.
|
||||
// linear_sweep(regular_ngon(n=3, d=50),
|
||||
// texture="rough", h=100, tex_depth=2,
|
||||
// texture="rough", h=100, tex_depth=.4,
|
||||
// tex_size=[20,20], style="min_edge",
|
||||
// convexity=10, scale=0.2, twist=120);
|
||||
// Example: As Function
|
||||
@@ -717,7 +717,7 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close
|
||||
// [24, 25, 35, 33], [33, 35, 34], [24, 33, 6, 31], [34, 35, 11, 7],
|
||||
// [35, 25, 32, 11], [30, 32, 25, 23]]
|
||||
// ];
|
||||
// front_half(y=3){
|
||||
// front_half(y=33){
|
||||
// cyl(d=14.5,h=1,anchor=BOT,rounding=1/3,$fa=1,$fs=.5);
|
||||
// linear_sweep(circle(d=12), h=12, scale=1.3, texture=diag_weave_vnf,
|
||||
// tex_size=[5,5], convexity=12);
|
||||
@@ -1041,7 +1041,7 @@ function linear_sweep(
|
||||
// path = [for(y=[-30:30]) [ 20-3*(1-cos((y+30)/60*360)),y]];
|
||||
// rotate_sweep(path, closed=false, texture=tile, tex_rot=90,
|
||||
// tex_size=[12,8], tex_depth=9, angle=360);
|
||||
// Example(3D,Med,NoAxes: A basket weave texture, here only half way around the circle to avoid clutter.
|
||||
// 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 half way around the circle to avoid clutter.
|
||||
// diag_weave_vnf = [
|
||||
// [[0.2, 0, 0], [0.8, 0, 0], [1, 0.2, 0.5], [1, 0.8, 0.5], [0.7, 0.5, 0.5],
|
||||
// [0.5, 0.3, 0], [0.2, 0, 0.5], [0.8, 0, 0.5], [1, 0.2, 1], [1, 0.8, 1],
|
||||
@@ -4016,7 +4016,6 @@ function _validate_texture(texture) =
|
||||
min_xy = point2d(bounds[0]),
|
||||
max_xy = point2d(bounds[1])
|
||||
)
|
||||
//assert(min_xy==[0,0] && max_xy==[1,1],"VNF tiles must span exactly from [0,0] to [1,1] in the X and Y components."))
|
||||
assert(all_nonnegative(concat(min_xy,[1,1]-max_xy)), "VNF tile X and Y components must be between 0 and 1.")
|
||||
let(
|
||||
verts = texture[0],
|
||||
@@ -4059,8 +4058,8 @@ function _textured_linear_sweep(
|
||||
frac = pos-ind,
|
||||
texh = scale<0 ? -(1-tilez - inset) * scale
|
||||
: (tilez - inset) * scale,
|
||||
base = lerp(bases[ind], select(bases,ind+1), frac),
|
||||
norm = unit(lerp(norms[ind], select(norms,ind+1), frac))
|
||||
base = lerp(select(bases,ind), select(bases,ind+1), frac),
|
||||
norm = unit(lerp(select(norms,ind), select(norms,ind+1), frac))
|
||||
)
|
||||
base + norm * texh,
|
||||
|
||||
@@ -4083,38 +4082,36 @@ function _textured_linear_sweep(
|
||||
samples = !is_vnf(texture)? len(texture[0]) :
|
||||
is_num(samples)? samples : 8,
|
||||
check_tex = _validate_texture(texture),
|
||||
sorted_tile =
|
||||
!is_vnf(texture)? texture :
|
||||
vnf_tile =
|
||||
!is_vnf(texture) || samples==1 ? texture
|
||||
:
|
||||
let(
|
||||
s = 1 / max(1, samples),
|
||||
vnf = samples<=1? texture :
|
||||
let(
|
||||
slice_us = list([s:s:1-s/2]),
|
||||
vnft1 = vnf_slice(texture, "X", slice_us),
|
||||
vnft = twist? vnf_slice(vnft1, "Y", slice_us) : vnft1,
|
||||
zvnf = [
|
||||
[
|
||||
for (p=vnft[0]) [
|
||||
slice_us = list([s:s:1-s/2]),
|
||||
vnft1 = vnf_slice(texture, "X", slice_us),
|
||||
vnft = twist? vnf_slice(vnft1, "Y", slice_us) : vnft1,
|
||||
zvnf = [
|
||||
[
|
||||
for (p=vnft[0]) [
|
||||
approx(p.x,0)? 0 : approx(p.x,1)? 1 : p.x,
|
||||
approx(p.y,0)? 0 : approx(p.y,1)? 1 : p.y,
|
||||
p.z
|
||||
]
|
||||
],
|
||||
vnft[1]
|
||||
]
|
||||
) zvnf
|
||||
) _vnf_sort_vertices(vnf, idx=[1,0]),
|
||||
vertzs = !is_vnf(sorted_tile)? undef :
|
||||
group_sort(sorted_tile[0], idx=1),
|
||||
edge_paths = is_vnf(sorted_tile) ? _tile_edge_path_list(sorted_tile,1) : undef,
|
||||
],
|
||||
vnft[1]
|
||||
]
|
||||
) zvnf,
|
||||
edge_paths = is_vnf(texture) ? _tile_edge_path_list(vnf_tile,1) : undef,
|
||||
tpath = is_def(edge_paths)
|
||||
? len(edge_paths[0])==0 ? [] : hstack([column(edge_paths[0][0],0), column(edge_paths[0][0],2)])
|
||||
: let(
|
||||
row = sorted_tile[0],
|
||||
row = texture[0],
|
||||
rlen = len(row)
|
||||
) [for (i = [0:1:rlen]) [i/rlen, row[i%rlen]]],
|
||||
edge_closed_paths = is_def(edge_paths) ? edge_paths[1] : [],
|
||||
tmat = scale(scale) * zrot(twist) * up(h/2),
|
||||
texcnt = is_vnf(texture) ? undef
|
||||
: [len(texture[0]), len(texture)],
|
||||
pre_skew_vnf = vnf_join([
|
||||
for (rgn = regions) let(
|
||||
walls_vnf = vnf_join([
|
||||
@@ -4125,19 +4122,16 @@ function _textured_linear_sweep(
|
||||
is_vector(tex_size,2)
|
||||
? [round(plen/tex_size.x), max(1,round(h/tex_size.y)), ]
|
||||
: [ceil(6*plen/h), 6],
|
||||
obases = resample_path(path, n=counts.x * samples, closed=true),
|
||||
onorms = path_normals(obases, closed=true),
|
||||
bases = list_wrap(obases),
|
||||
norms = list_wrap(onorms),
|
||||
bases = resample_path(path, n=counts.x * samples, closed=true),
|
||||
norms = path_normals(bases, closed=true),
|
||||
vnf = is_vnf(texture)
|
||||
? vnf_join( // VNF tile texture
|
||||
let(
|
||||
row_vnf = vnf_join([
|
||||
for (i = [0:1:(scale==1?0:counts.y-1)], j = [0:1:counts.x-1]) [
|
||||
[
|
||||
for (group = vertzs)
|
||||
each [
|
||||
for (vert = group) let(
|
||||
for (vert=vnf_tile[0])
|
||||
let(
|
||||
xy = transform_pt(j,vert.x,vert.z,samples, inset, tex_scale, bases, norms),
|
||||
pt = point3d(xy,vert.y),
|
||||
v = vert.y / counts.y,
|
||||
@@ -4149,9 +4143,8 @@ function _textured_linear_sweep(
|
||||
zrot(twist*(v+vv)) *
|
||||
zscale(h/counts.y)
|
||||
) apply(mat, pt)
|
||||
]
|
||||
],
|
||||
sorted_tile[1]
|
||||
vnf_tile[1]
|
||||
]
|
||||
])
|
||||
) [
|
||||
@@ -4168,7 +4161,6 @@ function _textured_linear_sweep(
|
||||
]
|
||||
)
|
||||
: let( // Heightfield texture
|
||||
texcnt = [len(texture[0]), len(texture)],
|
||||
tile_rows = [
|
||||
for (ti = [0:1:texcnt.y-1])
|
||||
path3d([
|
||||
@@ -4204,10 +4196,8 @@ function _textured_linear_sweep(
|
||||
is_vector(tex_size,2)
|
||||
? [round(plen/tex_size.x), max(1,round(h/tex_size.y)), ]
|
||||
: [ceil(6*plen/h), 6],
|
||||
obases = resample_path(path, n=counts.x * samples, closed=true),
|
||||
onorms = path_normals(obases, closed=true),
|
||||
bases = list_wrap(obases),
|
||||
norms = list_wrap(onorms),
|
||||
bases = resample_path(path, n=counts.x * samples, closed=true),
|
||||
norms = path_normals(bases, closed=true),
|
||||
nupath = [
|
||||
for (j = [0:1:counts.x-1], vert = tpath)
|
||||
transform_pt(j,vert.x,vert.y,samples,inset,tex_scale,bases,norms)
|
||||
@@ -4224,10 +4214,8 @@ function _textured_linear_sweep(
|
||||
is_vector(tex_size,2)
|
||||
? [round(plen/tex_size.x), max(1,round(h/tex_size.y)), ]
|
||||
: [ceil(6*plen/h), 6],
|
||||
obases = resample_path(path, n=counts.x * samples, closed=true),
|
||||
onorms = path_normals(obases, closed=true),
|
||||
bases = list_wrap(obases),
|
||||
norms = list_wrap(onorms),
|
||||
bases = resample_path(path, n=counts.x * samples, closed=true),
|
||||
norms = path_normals(bases, closed=true),
|
||||
modpaths = [for (j = [0:1:counts.x-1], cpath = edge_closed_paths)
|
||||
[for(vert = cpath)
|
||||
transform_pt(j,vert.x,vert.z,samples,inset,tex_scale,bases, norms)]
|
||||
@@ -4382,28 +4370,24 @@ function _textured_revolution(
|
||||
maxy = bounds[1].y,
|
||||
h = maxy - miny,
|
||||
circumf = 2 * PI * maxx,
|
||||
tile = !is_vnf(texture)? texture :
|
||||
tile = !is_vnf(texture) || samples==1 ? texture :
|
||||
let(
|
||||
utex = samples<=1? texture :
|
||||
let(
|
||||
s = 1 / samples,
|
||||
slices = list([s : s : 1-s/2]),
|
||||
vnfx = vnf_slice(texture, "X", slices),
|
||||
vnfy = inhibit_y_slicing? vnfx : vnf_slice(vnfx, "Y", slices),
|
||||
vnft = vnf_triangulate(vnfy),
|
||||
zvnf = [
|
||||
[
|
||||
for (p=vnft[0]) [
|
||||
approx(p.x,0)? 0 : approx(p.x,1)? 1 : p.x,
|
||||
approx(p.y,0)? 0 : approx(p.y,1)? 1 : p.y,
|
||||
p.z
|
||||
]
|
||||
],
|
||||
vnft[1]
|
||||
s = 1 / samples,
|
||||
slices = list([s : s : 1-s/2]),
|
||||
vnfx = vnf_slice(texture, "X", slices),
|
||||
vnfy = inhibit_y_slicing? vnfx : vnf_slice(vnfx, "Y", slices),
|
||||
vnft = vnf_triangulate(vnfy),
|
||||
zvnf = [
|
||||
[
|
||||
for (p=vnft[0]) [
|
||||
approx(p.x,0)? 0 : approx(p.x,1)? 1 : p.x,
|
||||
approx(p.y,0)? 0 : approx(p.y,1)? 1 : p.y,
|
||||
p.z
|
||||
]
|
||||
) zvnf
|
||||
) _vnf_sort_vertices(utex, idx=[0,1]),
|
||||
vertzs = is_vnf(texture)? group_sort(tile[0], idx=0) : undef,
|
||||
],
|
||||
vnft[1]
|
||||
]
|
||||
) zvnf,
|
||||
edge_paths = is_vnf(tile) ? _tile_edge_path_list(tile,1) : undef,
|
||||
bpath = is_def(edge_paths)
|
||||
? len(edge_paths[0])==0 ? [] : hstack([column(edge_paths[0][0],0), column(edge_paths[0][0],2)])
|
||||
@@ -4436,8 +4420,8 @@ function _textured_revolution(
|
||||
part = tileind * samples,
|
||||
ind = floor(part),
|
||||
frac = part - ind,
|
||||
base = lerp(bases[ind], select(bases,ind+1), frac),
|
||||
norm = unit(lerp(norms[ind], select(norms,ind+1), frac)),
|
||||
base = lerp(select(bases,ind), select(bases,ind+1), frac),
|
||||
norm = unit(lerp(select(norms,ind), select(norms,ind+1), frac)),
|
||||
scale = tex_scale * lookup(tileind/counts_y, taper_lup) * base.x/maxx,
|
||||
texh = scale<0 ? -(1-tilez - inset) * scale
|
||||
: (tilez - inset) * scale
|
||||
@@ -4452,26 +4436,21 @@ function _textured_revolution(
|
||||
is_vector(tex_size,2)? max(1,round(plen/tex_size.y)) : 6,
|
||||
obases = resample_path(path, n=counts_y * samples + (closed?0:1), closed=closed),
|
||||
onorms = path_normals(obases, closed=closed),
|
||||
rbases = closed? list_wrap(obases) : obases,
|
||||
rnorms = closed? list_wrap(onorms) : onorms,
|
||||
bases = xrot(90, p=path3d(rbases)),
|
||||
norms = xrot(90, p=path3d(rnorms)),
|
||||
bases = xrot(90, p=path3d(obases)),
|
||||
norms = xrot(90, p=path3d(onorms)),
|
||||
vnf = is_vnf(texture)
|
||||
? vnf_join([ // VNF tile texture
|
||||
for (j = [0:1:counts_y-1])
|
||||
[
|
||||
[
|
||||
for (group = vertzs) each [
|
||||
for (vert = group)
|
||||
for (vert = tile[0])
|
||||
let(xyz = transform_point(j + (1-vert.y),vert.z,counts_y,bases, norms))
|
||||
zrot(vert.x*angle/counts_x, p=xyz)
|
||||
]
|
||||
],
|
||||
tile[1]
|
||||
]
|
||||
])
|
||||
: let( // Heightfield texture
|
||||
texcnt = [len(texture[0]), len(texture)],
|
||||
tiles = transpose([
|
||||
for (j = [0,1], tj = [0:1:texcnt.x-1])
|
||||
if (j == 0 || tj == 0)
|
||||
@@ -4502,23 +4481,18 @@ function _textured_revolution(
|
||||
plen = path_length(path, closed=closed),
|
||||
counts_y = is_vector(counts,2)? counts.y :
|
||||
is_vector(tex_size,2)? max(1,round(plen/tex_size.y)) : 6,
|
||||
obases = resample_path(path, n=counts_y * samples + (closed?0:1), closed=closed),
|
||||
onorms = path_normals(obases, closed=closed),
|
||||
bases = closed? list_wrap(obases) : obases,
|
||||
norms = closed? list_wrap(onorms) : onorms,
|
||||
bases = resample_path(path, n=counts_y * samples + (closed?0:1), closed=closed),
|
||||
norms = path_normals(bases, closed=closed),
|
||||
ppath = is_vnf(texture)
|
||||
? [ // VNF tile texture
|
||||
for (j = [0:1:counts_y-1])
|
||||
//for (group = vertzs, vert = reverse(group))
|
||||
for(vert=side_open_path)
|
||||
for (j = [0:1:counts_y-1], vert=side_open_path)
|
||||
transform_point(j + (1 - vert.y),vert.z,counts_y,bases, norms)
|
||||
]
|
||||
: let( // Heightfield texture
|
||||
texcnt = [len(texture[0]), len(texture)]
|
||||
) [
|
||||
:
|
||||
[ // Heightfield texture
|
||||
for (i = [0:1:counts_y-(closed?1:0)], ti = [0:1:texcnt.y-1])
|
||||
if (i != counts_y || ti == 0)
|
||||
transform_point(i + (ti/texcnt.y),texture[ti][0],counts_y,bases, norms)
|
||||
if (i != counts_y || ti == 0)
|
||||
transform_point(i + (ti/texcnt.y),texture[ti][0],counts_y,bases, norms)
|
||||
],
|
||||
path = closed? ppath : [
|
||||
[0, ppath[0].y],
|
||||
@@ -4534,10 +4508,8 @@ function _textured_revolution(
|
||||
plen = path_length(path, closed=closed),
|
||||
counts_y = is_vector(counts,2)? counts.y :
|
||||
is_vector(tex_size,2)? max(1,round(plen/tex_size.y)) : 6,
|
||||
obases = resample_path(path, n=counts_y * samples + (closed?0:1), closed=closed),
|
||||
onorms = path_normals(obases, closed=closed),
|
||||
bases = closed? list_wrap(obases) : obases,
|
||||
norms = closed? list_wrap(onorms) : onorms,
|
||||
bases = resample_path(path, n=counts_y * samples + (closed?0:1), closed=closed),
|
||||
norms = path_normals(bases, closed=closed),
|
||||
modpaths = [for (j = [0:1:counts_y-1], cpath=side_closed_paths)
|
||||
[for(vert=cpath)
|
||||
transform_point(j + (1 - vert.y),vert.z,counts_y,bases, norms)]
|
||||
@@ -4557,10 +4529,8 @@ function _textured_revolution(
|
||||
is_vector(tex_size,2)? max(1,round(plen/tex_size.y)) : 6,
|
||||
obases = resample_path(rgn[0], n=counts_y * samples + (closed?0:1), closed=closed),
|
||||
onorms = path_normals(obases, closed=closed),
|
||||
rbases = closed? list_wrap(obases) : obases,
|
||||
rnorms = closed? list_wrap(onorms) : onorms,
|
||||
bases = xrot(90, p=path3d(rbases)),
|
||||
norms = xrot(90, p=path3d(rnorms)),
|
||||
bases = xrot(90, p=path3d(obases)),
|
||||
norms = xrot(90, p=path3d(onorms)),
|
||||
caps_vnf = vnf_join([
|
||||
for (epath=edge_closed_paths, j = [-1,0])
|
||||
let(
|
||||
|
47
vnf.scad
47
vnf.scad
@@ -27,13 +27,14 @@
|
||||
EMPTY_VNF = [[],[]]; // The standard empty VNF with no vertices or faces.
|
||||
|
||||
|
||||
// Function: vnf_vertex_array()
|
||||
// Function&Module: vnf_vertex_array()
|
||||
// Synopsis: Returns a VNF structure from a rectangular vertex list.
|
||||
// SynTags: VNF
|
||||
// SynTags: VNF, Geom
|
||||
// Topics: VNF Generators, Lists
|
||||
// See Also: vnf_tri_array(), vnf_join(), vnf_from_polygons(), vnf_from_region()
|
||||
// Usage:
|
||||
// vnf = vnf_vertex_array(points, [caps=], [cap1=], [cap2=], [style=], [reverse=], [col_wrap=], [row_wrap=], [triangulate=]);
|
||||
// vnf_vertex_array(points, [caps=], [cap1=], [cap2=], [style=], [reverse=], [col_wrap=], [row_wrap=], [triangulate=],...) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a VNF structure from a rectangular vertex list, creating edges that connect the adjacent vertices in the vertex list
|
||||
// and creating the faces defined by those edges. You can optionally create the edges and faces to wrap the last column
|
||||
@@ -58,6 +59,17 @@ EMPTY_VNF = [[],[]]; // The standard empty VNF with no vertices or faces.
|
||||
// reverse = If true, reverse all face normals.
|
||||
// style = The style of subdividing the quads into faces. Valid options are "default", "alt", "flip1", "flip2", "min_edge", "min_area", "quincunx", "convex" and "concave".
|
||||
// triangulate = If true, triangulates endcaps to resolve possible CGAL issues. This can be an expensive operation if the endcaps are complex. Default: false
|
||||
// convexity = (module) Max number of times a line could intersect a wall of the shape.
|
||||
// cp = (module) Centerpoint for determining intersection anchors or centering the shape. Determines the base of the anchor vector. Can be "centroid", "mean", "box" or a 3D point. Default: "centroid"
|
||||
// anchor = (module) Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `"origin"`
|
||||
// spin = (module) Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = (module) Vector to rotate top toward, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
// atype = (module) Select "hull" or "intersect" anchor type. Default: "hull"
|
||||
// Anchor Types:
|
||||
// "hull" = Anchors to the virtual convex hull of the shape.
|
||||
// "intersect" = Anchors to the surface of the shape.
|
||||
// Named Anchors:
|
||||
// "origin" = Anchor at the origin, oriented UP.
|
||||
// Example(3D):
|
||||
// vnf = vnf_vertex_array(
|
||||
// points=[
|
||||
@@ -160,6 +172,23 @@ EMPTY_VNF = [[],[]]; // The standard empty VNF with no vertices or faces.
|
||||
// apply(m, [ [rgroove[0].x,0,-z], each rgroove, [last(rgroove).x,0,-z] ])
|
||||
// ], caps=true, col_wrap=true, reverse=true);
|
||||
// vnf_polyhedron(vnf, convexity=8);
|
||||
|
||||
module vnf_vertex_array(
|
||||
points,
|
||||
caps, cap1, cap2,
|
||||
col_wrap=false,
|
||||
row_wrap=false,
|
||||
reverse=false,
|
||||
style="default",
|
||||
triangulate = false,
|
||||
convexity=2, cp="centroid", anchor="origin", spin=0, orient=UP, atype="hull")
|
||||
{
|
||||
vnf = vnf_vertex_array(points=points, caps=caps, cap1=cap2, cap2=cap2,
|
||||
col_wrap=col_wrap, row_wrap=row_wrap, reverse=reverse, style=style,triangulate=triangulate);
|
||||
vnf_polyhedron(vnf, convexity=2, cp="centroid", anchor="origin", spin=0, orient=UP, atype="hull") children();
|
||||
}
|
||||
|
||||
|
||||
function vnf_vertex_array(
|
||||
points,
|
||||
caps, cap1, cap2,
|
||||
@@ -1013,20 +1042,6 @@ function _detri_combine_faces(edgelist,faces,normals,facelist,curface) =
|
||||
|
||||
|
||||
|
||||
function _vnf_sort_vertices(vnf, idx=[2,1,0]) =
|
||||
let(
|
||||
verts = vnf[0],
|
||||
faces = vnf[1],
|
||||
vidx = sortidx(verts, idx=idx),
|
||||
rvidx = sortidx(vidx),
|
||||
sorted_vnf = [
|
||||
[ for (i = vidx) verts[i] ],
|
||||
[ for (face = faces) [ for (i = face) rvidx[i] ] ],
|
||||
]
|
||||
) sorted_vnf;
|
||||
|
||||
|
||||
|
||||
|
||||
// Function: vnf_slice()
|
||||
// Synopsis: Slice the faces of a VNF along an axis.
|
||||
|
Reference in New Issue
Block a user