diff --git a/regions.scad b/regions.scad index 73d1f39..7f94962 100644 --- a/regions.scad +++ b/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 diff --git a/skin.scad b/skin.scad index 529ecd4..9599986 100644 --- a/skin.scad +++ b/skin.scad @@ -2958,13 +2958,13 @@ function associate_vertices(polygons, split, curpoly=0) = // 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. -// tex = texture("dimples"); +// tex = texture("dimples", $fn=16); // linear_sweep( // rect(30), texture=tex, h=30, // 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. -// tex = texture("dots"); +// tex = texture("dots", $fn=16); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] diff --git a/vnf.scad b/vnf.scad index c6cbc4f..9f09956 100644 --- a/vnf.scad +++ b/vnf.scad @@ -1414,6 +1414,53 @@ function vnf_bend(vnf,r,d,axis="Z") = ) [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 /// Internal Module: _show_vertices()