mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-04 03:09:45 +00:00
Merge pull request #1344 from adrianVmariano/master
hull returns points plus doc fixes
This commit is contained in:
commit
34a8513723
5 changed files with 119 additions and 22 deletions
35
regions.scad
35
regions.scad
|
@ -1396,4 +1396,39 @@ module exclusive_or() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Function&Module: hull_region()
|
||||||
|
// Synopsis: Compute convex hull of region or 2d path
|
||||||
|
// SynTags: Geom, Path
|
||||||
|
// Topics: Regions, Polygons, Shapes2D
|
||||||
|
// Usage:
|
||||||
|
// path = hull_region(region);
|
||||||
|
// hull_region(region);
|
||||||
|
// Description:
|
||||||
|
// Given a path, or a region, compute the convex hull
|
||||||
|
// and return it as a path. This differs from {{hull()}} and {{hull2d_path()}} which
|
||||||
|
// return an index list into the point list. As a module invokes the native hull() on
|
||||||
|
// the specified region.
|
||||||
|
// Arguments:
|
||||||
|
// region = region or path listing points to compute the hull from.
|
||||||
|
// Example(2D, NoAxes):
|
||||||
|
// data = [star(id=10,od=20,n=9),
|
||||||
|
// right(30, star(id=12,od=25, n=7))];
|
||||||
|
// stroke(data);
|
||||||
|
// stroke([hull_region(data)],color="red");
|
||||||
|
function hull_region(region) =
|
||||||
|
assert(is_path(region) || is_region(region))
|
||||||
|
let(
|
||||||
|
pts = is_region(region) ? flatten(region)
|
||||||
|
: region,
|
||||||
|
order = hull2d_path(pts)
|
||||||
|
)
|
||||||
|
select(pts,order);
|
||||||
|
|
||||||
|
module hull_region(region)
|
||||||
|
{
|
||||||
|
hull()region(region);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
||||||
|
|
|
@ -1509,7 +1509,7 @@ function cyl(
|
||||||
teardrop=false,
|
teardrop=false,
|
||||||
from_end, from_end1, from_end2,
|
from_end, from_end1, from_end2,
|
||||||
texture, tex_size=[5,5], tex_reps, tex_counts,
|
texture, tex_size=[5,5], tex_reps, tex_counts,
|
||||||
tex_inset=false, tex_rot=false,
|
tex_inset=false, tex_rot=0,
|
||||||
tex_scale, tex_depth, tex_samples, length, height,
|
tex_scale, tex_depth, tex_samples, length, height,
|
||||||
tex_taper, style, tex_style,
|
tex_taper, style, tex_style,
|
||||||
anchor, spin=0, orient=UP
|
anchor, spin=0, orient=UP
|
||||||
|
@ -1670,7 +1670,7 @@ module cyl(
|
||||||
teardrop=false,
|
teardrop=false,
|
||||||
from_end, from_end1, from_end2,
|
from_end, from_end1, from_end2,
|
||||||
texture, tex_size=[5,5], tex_reps, tex_counts,
|
texture, tex_size=[5,5], tex_reps, tex_counts,
|
||||||
tex_inset=false, tex_rot=false,
|
tex_inset=false, tex_rot=0,
|
||||||
tex_scale, tex_depth, tex_samples, length, height,
|
tex_scale, tex_depth, tex_samples, length, height,
|
||||||
tex_taper, style, tex_style,
|
tex_taper, style, tex_style,
|
||||||
anchor, spin=0, orient=UP
|
anchor, spin=0, orient=UP
|
||||||
|
|
51
skin.scad
51
skin.scad
|
@ -708,7 +708,7 @@ module linear_sweep(
|
||||||
twist=0, scale=1, shift=[0,0],
|
twist=0, scale=1, shift=[0,0],
|
||||||
slices, maxseg, style="default", convexity, caps=true,
|
slices, maxseg, style="default", convexity, caps=true,
|
||||||
texture, tex_size=[5,5], tex_reps, tex_counts,
|
texture, tex_size=[5,5], tex_reps, tex_counts,
|
||||||
tex_inset=false, tex_rot=false,
|
tex_inset=false, tex_rot=0,
|
||||||
tex_depth, tex_scale, tex_samples,
|
tex_depth, tex_scale, tex_samples,
|
||||||
cp, atype="hull", h,l,length,
|
cp, atype="hull", h,l,length,
|
||||||
anchor, spin=0, orient=UP
|
anchor, spin=0, orient=UP
|
||||||
|
@ -761,7 +761,7 @@ function linear_sweep(
|
||||||
slices, maxseg, style="default", caps=true,
|
slices, maxseg, style="default", caps=true,
|
||||||
cp, atype="hull", h,
|
cp, atype="hull", h,
|
||||||
texture, tex_size=[5,5], tex_reps, tex_counts,
|
texture, tex_size=[5,5], tex_reps, tex_counts,
|
||||||
tex_inset=false, tex_rot=false,
|
tex_inset=false, tex_rot=0,
|
||||||
tex_scale, tex_depth, tex_samples, h, l, length,
|
tex_scale, tex_depth, tex_samples, h, l, length,
|
||||||
anchor, spin=0, orient=UP
|
anchor, spin=0, orient=UP
|
||||||
) =
|
) =
|
||||||
|
@ -961,7 +961,7 @@ function linear_sweep(
|
||||||
function rotate_sweep(
|
function rotate_sweep(
|
||||||
shape, angle=360,
|
shape, angle=360,
|
||||||
texture, tex_size=[5,5], tex_counts, tex_reps,
|
texture, tex_size=[5,5], tex_counts, tex_reps,
|
||||||
tex_inset=false, tex_rot=false,
|
tex_inset=false, tex_rot=0,
|
||||||
tex_scale, tex_depth, tex_samples,
|
tex_scale, tex_depth, tex_samples,
|
||||||
tex_taper, shift=[0,0], closed=true,
|
tex_taper, shift=[0,0], closed=true,
|
||||||
style="min_edge", cp="centroid",
|
style="min_edge", cp="centroid",
|
||||||
|
@ -1022,7 +1022,7 @@ function rotate_sweep(
|
||||||
module rotate_sweep(
|
module rotate_sweep(
|
||||||
shape, angle=360,
|
shape, angle=360,
|
||||||
texture, tex_size=[5,5], tex_counts, tex_reps,
|
texture, tex_size=[5,5], tex_counts, tex_reps,
|
||||||
tex_inset=false, tex_rot=false,
|
tex_inset=false, tex_rot=0,
|
||||||
tex_scale, tex_depth, tex_samples,
|
tex_scale, tex_depth, tex_samples,
|
||||||
tex_taper, shift=[0,0],
|
tex_taper, shift=[0,0],
|
||||||
style="min_edge",
|
style="min_edge",
|
||||||
|
@ -2737,7 +2737,7 @@ function associate_vertices(polygons, split, curpoly=0) =
|
||||||
// Values in the height field should range from 0 to 1. A zero height
|
// Values in the height field should range from 0 to 1. A zero height
|
||||||
// in the height field corresponds to the height of the surface and 1
|
// in the height field corresponds to the height of the surface and 1
|
||||||
// the highest point in the texture above the surface being textured.
|
// the highest point in the texture above the surface being textured.
|
||||||
// Figure(2D,Big,NoScales): Here is a 2d texture described by a "grid" that just contains a single row. Such a texture can be used to create ribbing. The texture is `[[0, 1, 1, 0]]`, and the fixture shows three repetitions of the basic texture unit.
|
// Figure(2D,Big,NoScales,VPT=[6.21418,0.242814,0],VPD=28.8248,VPR=[0,0,0]): Here is a 2d texture described by a "grid" that just contains a single row. Such a texture can be used to create ribbing. The texture is `[[0, 1, 1, 0]]`, and the fixture shows three repetitions of the basic texture unit.
|
||||||
// ftex1 = [0,1,1,0,0];
|
// ftex1 = [0,1,1,0,0];
|
||||||
// stroke( transpose([count(5),ftex1]), dots=true, dots_width=3,width=.05);
|
// stroke( transpose([count(5),ftex1]), dots=true, dots_width=3,width=.05);
|
||||||
// right(4)stroke( transpose([count(5),ftex1]), dots=true, width=.05,dots_color="red",color="blue",dots_width=3);
|
// right(4)stroke( transpose([count(5),ftex1]), dots=true, width=.05,dots_color="red",color="blue",dots_width=3);
|
||||||
|
@ -2753,7 +2753,7 @@ function associate_vertices(polygons, split, curpoly=0) =
|
||||||
// is correctly designed to span the range from 0 to 1. The `tex_depth` parameter can adjust
|
// is correctly designed to span the range from 0 to 1. The `tex_depth` parameter can adjust
|
||||||
// this dimension of a texture without changing anything else, and setting `tex_depth` negative
|
// this dimension of a texture without changing anything else, and setting `tex_depth` negative
|
||||||
// will invert a texture.
|
// will invert a texture.
|
||||||
// Figure(2D,Big,NoScales):
|
// Figure(2D,Big,NoScales,VPR=[0,0,0],VPT=[6.86022,-1.91238,0],VPD=28.8248):
|
||||||
// ftex1 = [0,1,1,0,0];
|
// ftex1 = [0,1,1,0,0];
|
||||||
// left(0)color(.6*[1,1,1])rect([12,1],anchor=BACK+LEFT);
|
// left(0)color(.6*[1,1,1])rect([12,1],anchor=BACK+LEFT);
|
||||||
// stroke( transpose([count(5),ftex1]), dots=true, dots_width=3,width=.05);
|
// stroke( transpose([count(5),ftex1]), dots=true, dots_width=3,width=.05);
|
||||||
|
@ -2783,8 +2783,10 @@ function associate_vertices(polygons, split, curpoly=0) =
|
||||||
// If you want to keep the texture the same size but make the slope
|
// If you want to keep the texture the same size but make the slope
|
||||||
// steeper you need to add more points to make the uniform grid fine enough
|
// steeper you need to add more points to make the uniform grid fine enough
|
||||||
// to represent the slope you want. This means that creating sharp edges
|
// to represent the slope you want. This means that creating sharp edges
|
||||||
// can require a large number of points, resulting in longer run times.
|
// can require a large number of points, resulting in longer run times.
|
||||||
// Figure(2D,Big,NoScales):
|
// When using the built-in textures you can control the number of points
|
||||||
|
// using the `n=` argument to {{texture()}}.
|
||||||
|
// Figure(2D,Big,NoScales,VPT=[6.21418,0.242814,0],VPD=28.8248,VPR=[0,0,0]):
|
||||||
// ftex2 = xscale(4/11,transpose([count(12),[0,1,1,1,1,1,1,1,1,1,0,0]]));
|
// ftex2 = xscale(4/11,transpose([count(12),[0,1,1,1,1,1,1,1,1,1,0,0]]));
|
||||||
// stroke( ftex2, dots=true, dots_width=3,width=.05);
|
// stroke( ftex2, dots=true, dots_width=3,width=.05);
|
||||||
// right(4)stroke( ftex2, dots=true, width=.05,dots_color="red",color="blue",dots_width=3);
|
// right(4)stroke( ftex2, dots=true, width=.05,dots_color="red",color="blue",dots_width=3);
|
||||||
|
@ -2806,7 +2808,7 @@ function associate_vertices(polygons, split, curpoly=0) =
|
||||||
// [0,0,0,0]]
|
// [0,0,0,0]]
|
||||||
// ```
|
// ```
|
||||||
// and we show the 3D triangulations produced by the different styles:
|
// and we show the 3D triangulations produced by the different styles:
|
||||||
// Figure(3D,Big,NoAxes,VPR=[39.2,0,13.3],VPT=[3.76242,-5.50969,4.51854],VPD=32.0275):
|
// Figure(3D,Big,NoAxes,VPR=[45.5,0,18.2],VPT=[2.3442,-6.25815,3.91529],VPD=35.5861):
|
||||||
// tex = [
|
// tex = [
|
||||||
// [0,0,0,0,0],
|
// [0,0,0,0,0],
|
||||||
// [0,1,1,0,0],
|
// [0,1,1,0,0],
|
||||||
|
@ -2815,18 +2817,20 @@ function associate_vertices(polygons, split, curpoly=0) =
|
||||||
// [0,0,0,0,0]
|
// [0,0,0,0,0]
|
||||||
// ];
|
// ];
|
||||||
// hm = [for(i=[0:4]) [for(j=[0:4]) [i,-j,tex[i][j]]]];
|
// hm = [for(i=[0:4]) [for(j=[0:4]) [i,-j,tex[i][j]]]];
|
||||||
// types = ["quincunx", "convex", "concave","default","alt","min_edge"];
|
// types = ["quincunx", "convex", "concave","min_area", "default","alt","min_edge"];
|
||||||
// grid2d(spacing=5, n=[3,2]){
|
// grid_copies(spacing=5, n=[4,2]){
|
||||||
// let(s = types[$row*3+$col]){
|
// let(s = types[$row*4+$col]){
|
||||||
|
// if (is_def(s)){
|
||||||
// vnf_polyhedron(vnf_vertex_array(hm,style=s));
|
// vnf_polyhedron(vnf_vertex_array(hm,style=s));
|
||||||
// if ($row==1)
|
// if ($row==1)
|
||||||
// back(.8)right(2)rotate($vpr)color("black")text(s,size=.5,anchor=CENTER);
|
// back(.8)right(2)rotate($vpr)color("black")text(s,size=.5,anchor=CENTER);
|
||||||
// else
|
// else
|
||||||
// fwd(4.7)right(2)rotate($vpr)color("black")text(s,size=.5,anchor=CENTER);
|
// fwd(4.7)right(2)rotate($vpr)color("black")text(s,size=.5,anchor=CENTER);
|
||||||
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// Continues:
|
// Continues:
|
||||||
// Note that of the six available styles, five produce a different result. There may exist some concave shape where none of the styles
|
// Note that of the seven available styles, five produce a different result. There may exist some concave shape where none of the styles
|
||||||
// produce the right result everywhere on the shape. If this happens it would be another limitation of height field textures. (If you have an
|
// produce the right result everywhere on the shape. If this happens it would be another limitation of height field textures. (If you have an
|
||||||
// example of such a texture and shape please let us know!)
|
// example of such a texture and shape please let us know!)
|
||||||
// Subsection: VNF Textures
|
// Subsection: VNF Textures
|
||||||
|
@ -2859,8 +2863,19 @@ function associate_vertices(polygons, split, curpoly=0) =
|
||||||
// caps=false);
|
// caps=false);
|
||||||
// tile = move([0,1/2,2/3],yrot(90,shape));
|
// tile = move([0,1/2,2/3],yrot(90,shape));
|
||||||
// vnf_polyhedron(tile);
|
// vnf_polyhedron(tile);
|
||||||
|
// Continues:
|
||||||
|
// A VNF texture provides a flat structure. In order to apply this structure to a cylinder or other curved object, the VNF must be sliced
|
||||||
|
// and "folded" so it can follow the curve. This folding is controlled by the `tex_samples` parameter to {{cyl()}}, {{linear_sweep()}},
|
||||||
|
// and {{rotate_sweep()}}. Note that you specify it when you **use** the texture, not when you create it. This differs from height
|
||||||
|
// fields, where the analogous parameter is the `n=` parameter of the {{texture()}} function. When `tex_samples` is too small, only the
|
||||||
|
// points given in the VNF will follow the surface, resulting in a blocky look and geometrical artifacts.
|
||||||
|
// Figure(3D,NoAxes): On the left the `tex_samples` value is small and the texture is blocky. On the right, the default value of 8 allows a reasonable fit to the cylinder.
|
||||||
|
// xdistribute(spacing=5){
|
||||||
|
// cyl(d=10/PI, h=5, chamfer=0,
|
||||||
|
// texture=texture("bricks_vnf"), tex_samples=1, tex_reps=[6,3], tex_depth=.2);
|
||||||
|
// cyl(d=10/PI, h=5, chamfer=0,
|
||||||
|
// texture=texture("bricks_vnf"), tex_samples=8, tex_reps=[6,3], tex_depth=.2);
|
||||||
|
// }
|
||||||
|
|
||||||
// Function: texture()
|
// Function: texture()
|
||||||
// Topics: Textures, Knurling
|
// Topics: Textures, Knurling
|
||||||
|
@ -2958,13 +2973,13 @@ function associate_vertices(polygons, split, curpoly=0) =
|
||||||
// tex_size=[10,10]
|
// tex_size=[10,10]
|
||||||
// );
|
// );
|
||||||
// Example(3D): **"dimples"** (VNF) = Round divots. Specify `$fn` to set the number of segments on the cone (will be rounded to a multiple of 4). If you use $fa and $fs then the number of segments is determined for the original VNF scale of 1x1. Giving `border=` specifies the horizontal width of the flat border region between the tile edges and the edge of the dimple. Must be nonnegative and strictly less than 0.5. Default: 0.05.
|
// Example(3D): **"dimples"** (VNF) = Round divots. Specify `$fn` to set the number of segments on the cone (will be rounded to a multiple of 4). If you use $fa and $fs then the number of segments is determined for the original VNF scale of 1x1. Giving `border=` specifies the horizontal width of the flat border region between the tile edges and the edge of the dimple. Must be nonnegative and strictly less than 0.5. Default: 0.05.
|
||||||
// tex = texture("dimples");
|
// tex = texture("dimples", $fn=16);
|
||||||
// linear_sweep(
|
// linear_sweep(
|
||||||
// rect(30), texture=tex, h=30,
|
// rect(30), texture=tex, h=30,
|
||||||
// tex_size=[10,10]
|
// tex_size=[10,10]
|
||||||
// );
|
// );
|
||||||
// Example(3D): **"dots"** (VNF) = Raised round bumps. Specify `$fn` to set the number of segments on the cone (will be rounded to a multiple of 4). If you use $fa and $fs then the number of segments is determined for the original VNF scale of 1x1. Giving `border=` specifies the horizontal width of the flat border region between the tile edge and the edge of the dots. Must be nonnegative and strictly less than 0.5. Default: 0.05.
|
// Example(3D): **"dots"** (VNF) = Raised round bumps. Specify `$fn` to set the number of segments on the cone (will be rounded to a multiple of 4). If you use $fa and $fs then the number of segments is determined for the original VNF scale of 1x1. Giving `border=` specifies the horizontal width of the flat border region between the tile edge and the edge of the dots. Must be nonnegative and strictly less than 0.5. Default: 0.05.
|
||||||
// tex = texture("dots");
|
// tex = texture("dots", $fn=16);
|
||||||
// linear_sweep(
|
// linear_sweep(
|
||||||
// rect(30), texture=tex, h=30,
|
// rect(30), texture=tex, h=30,
|
||||||
// tex_size=[10,10]
|
// tex_size=[10,10]
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
BOSL_VERSION = [2,0,686];
|
BOSL_VERSION = [2,0,688];
|
||||||
|
|
||||||
|
|
||||||
// Section: BOSL Library Version Functions
|
// Section: BOSL Library Version Functions
|
||||||
|
|
49
vnf.scad
49
vnf.scad
|
@ -54,7 +54,7 @@ EMPTY_VNF = [[],[]]; // The standard empty VNF with no vertices or faces.
|
||||||
// col_wrap = If true, add faces to connect the last column to the first.
|
// col_wrap = If true, add faces to connect the last column to the first.
|
||||||
// row_wrap = If true, add faces to connect the last row to the first.
|
// row_wrap = If true, add faces to connect the last row to the first.
|
||||||
// reverse = If true, reverse all face normals.
|
// reverse = If true, reverse all face normals.
|
||||||
// style = The style of subdividing the quads into faces. Valid options are "default", "alt", "min_edge", "quincunx", "convex" and "concave".
|
// style = The style of subdividing the quads into faces. Valid options are "default", "alt", "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
|
// triangulate = If true, triangulates endcaps to resolve possible CGAL issues. This can be an expensive operation if the endcaps are complex. Default: false
|
||||||
// Example(3D):
|
// Example(3D):
|
||||||
// vnf = vnf_vertex_array(
|
// vnf = vnf_vertex_array(
|
||||||
|
@ -1414,6 +1414,53 @@ function vnf_bend(vnf,r,d,axis="Z") =
|
||||||
) [new_vert,sliced[1]];
|
) [new_vert,sliced[1]];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Function&Module: vnf_hull()
|
||||||
|
// Synopsis: Compute convex hull of VNF or 3d path
|
||||||
|
// Usage:
|
||||||
|
// vnf_hull = hull_vnf(vnf);
|
||||||
|
// hull_vnf(vnf,[fast]);
|
||||||
|
// Description:
|
||||||
|
// Given a VNF or a list of 3d points, compute the convex hull
|
||||||
|
// and return it as a VNF. This differs from {{hull()}} and {{hull3d_faces()}} which
|
||||||
|
// return just the face list referenced to the input point list. Note that the point
|
||||||
|
// list that is returned will contain all the points that are actually used in the input
|
||||||
|
// VNF, which may be many more points than are needed to represent the convex hull.
|
||||||
|
// This is not usually a problem, but you can run the somewhat slow {{vnf_drop_unused_points()}}
|
||||||
|
// function to fix this if necessary.
|
||||||
|
// Arguments:
|
||||||
|
// region = region or path listing points to compute the hull from.
|
||||||
|
// fast = (module only) if input is a point list (not a VNF) use a fasterer cheat that may handle more points, but could emit warnings. Ignored if input is a VNF. Default: false.
|
||||||
|
// Example(3D,Big,NoAxes): Input is a VNF
|
||||||
|
// ellipse = xscale(2, p=circle($fn=48, r=3));
|
||||||
|
// pentagon = subdivide_path(pentagon(r=1), 20);
|
||||||
|
// vnf=path_sweep(pentagon, path3d(ellipse),
|
||||||
|
// closed=true, twist=360*2);
|
||||||
|
// vnfhull = vnf_hull(vnf);
|
||||||
|
// vnf_polyhedron(vnf);
|
||||||
|
// move([10,10])
|
||||||
|
// vnf_polyhedron(vnfhull);
|
||||||
|
// Example(2D, NoAxes): Input is a point list
|
||||||
|
// h=helix(l=40, turns=1, r=8);
|
||||||
|
// color("red")move_copies(h)
|
||||||
|
// sphere(r=0.5,$fn=12);
|
||||||
|
// vnf_polyhedron(vnf_hull(h));
|
||||||
|
function vnf_hull(vnf) =
|
||||||
|
assert(is_vnf(vnf) || is_path(vnf,3),"Input must be a VNF or a 3d path")
|
||||||
|
let(
|
||||||
|
pts = is_vnf(vnf) ? select(vnf[0],unique(flatten(vnf[1])))
|
||||||
|
: vnf,
|
||||||
|
faces = hull3d_faces(pts)
|
||||||
|
)
|
||||||
|
[pts, faces];
|
||||||
|
|
||||||
|
module vnf_hull(vnf, fast=false)
|
||||||
|
{
|
||||||
|
if (is_vnf(vnf)) hull()vnf_polyhedron(vnf);
|
||||||
|
else hull_points(vnf, fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Section: Debugging Polyhedrons
|
// Section: Debugging Polyhedrons
|
||||||
|
|
||||||
/// Internal Module: _show_vertices()
|
/// Internal Module: _show_vertices()
|
||||||
|
|
Loading…
Reference in a new issue