Added showdots= and showpatch= to trace_bezier_patch().

This commit is contained in:
Revar Desmera 2020-03-27 20:43:54 -07:00
parent 88a4557012
commit 5e4889652b
2 changed files with 62 additions and 47 deletions

View file

@ -331,36 +331,40 @@ function bezier_polyline(bezier, splinesteps=16, N=3) = let(
// Usage: // Usage:
// path_to_bezier(path,[tangent],[k],[closed]); // path_to_bezier(path,[tangent],[k],[closed]);
// Description: // Description:
// Given an input path and optional path of tangent vectors, computes a cubic (degree 3) bezier path that passes // Given an input path and optional path of tangent vectors, computes a cubic (degree 3) bezier path
// through every point on the input path and matches the tangent vectors. If you do not supply // that passes through every point on the input path and matches the tangent vectors. If you do not
// the tangent it will be computed using path_tangents. If the path is closed specify this // supply the tangent it will be computed using path_tangents. If the path is closed specify this
// by setting closed=true. If you specify the curvature parameter k it scales the tangent vectors, // by setting closed=true. If you specify the curvature parameter k it scales the tangent vectors,
// which will increase or decrease the curvature of the interpolated bezier. Negative values of k create loops at the corners, // which will increase or decrease the curvature of the interpolated bezier. Negative values of k
// so they are not allowed. Sufficiently large k values will also produce loops. // create loops at the corners, so they are not allowed. Sufficiently large k values will also
// produce loops.
// Arguments: // Arguments:
// path = path of points to define the bezier // path = path of points to define the bezier
// tangents = optional list of tangent vectors at every point // tangents = optional list of tangent vectors at every point
// k = curvature parameter, a scalar or vector to adjust curvature at each point // k = curvature parameter, a scalar or vector to adjust curvature at each point
// closed = set to true for a closed path. Default: false // closed = set to true for a closed path. Default: false
function path_to_bezier(path, tangents, k, closed=false) = function path_to_bezier(path, tangents, k, closed=false) =
assert(is_path(path,dim=undef),"Input path is not a valid path") assert(is_path(path,dim=undef),"Input path is not a valid path")
assert(is_undef(tangents) || is_path(tangents,dim=len(path[0])),"Tangents must be a path of the same dimension as the input path") assert(is_undef(tangents) || is_path(tangents,dim=len(path[0])),"Tangents must be a path of the same dimension as the input path")
assert(is_undef(tangents) || len(path)==len(tangents), "Input tangents must be the same length as the input path") assert(is_undef(tangents) || len(path)==len(tangents), "Input tangents must be the same length as the input path")
let( let(
k = is_undef(k) ? repeat(1, len(path)) : k = is_undef(k) ? repeat(1, len(path)) :
is_list(k) ? k : repeat(k, len(path)), is_list(k) ? k : repeat(k, len(path)),
k_bad = [for(entry=k) if (entry<0) entry] k_bad = [for(entry=k) if (entry<0) entry]
) )
assert(len(k)==len(path), "Curvature parameter k must have the same length as the path") assert(len(k)==len(path), "Curvature parameter k must have the same length as the path")
assert(k_bad==[], "Curvature parameter k must be a nonnegative number or list of nonnegative numbers") assert(k_bad==[], "Curvature parameter k must be a nonnegative number or list of nonnegative numbers")
let( let(
tangents = is_def(tangents)? tangents : deriv(path, closed=closed), tangents = is_def(tangents)? tangents : deriv(path, closed=closed),
lastpt = len(path) - (closed?0:1) lastpt = len(path) - (closed?0:1)
) ) [
[for(i=[0:lastpt-1]) each [path[i], for(i=[0:lastpt-1]) each [
path[i]+k[i]*tangents[i]/3, path[i],
select(path,i+1)-select(k,i+1)*select(tangents,i+1)/3], path[i]+k[i]*tangents[i]/3,
select(path,lastpt)]; select(path,i+1)-select(k,i+1)*select(tangents,i+1)/3
],
select(path,lastpt)
];
// Function: fillet_path() // Function: fillet_path()
@ -827,7 +831,7 @@ function bezier_patch(patch, splinesteps=16, vnf=EMPTY_VNF, style="default") =
] ]
], ],
vnf = vnf_vertex_array(pts, style=style, vnf=vnf) vnf = vnf_vertex_array(pts, style=style, vnf=vnf)
) vnf; ) vnf;
function _tri_count(n) = (n*(1+n))/2; function _tri_count(n) = (n*(1+n))/2;
@ -977,14 +981,18 @@ module bezier_polyhedron(patches=[], splinesteps=16, vnf=EMPTY_VNF, style="defau
// Module: trace_bezier_patches() // Module: trace_bezier_patches()
// Usage: // Usage:
// trace_bezier_patches(patches, [size], [showcps], [splinesteps]); // trace_bezier_patches(patches, [size], [splinesteps], [showcps], [showdots], [showpatch], [convexity], [style]);
// Description: // Description:
// Shows the surface, and optionally, control points of a list of bezier patches. // Shows the surface, and optionally, control points of a list of bezier patches.
// Arguments: // Arguments:
// patches = A list of rectangular bezier patches. // patches = A list of rectangular bezier patches.
// splinesteps = Number of steps to divide each bezier segment into. default=16 // splinesteps = Number of steps to divide each bezier segment into. default=16
// showcps = If true, show the controlpoints as well as the surface. // showcps = If true, show the controlpoints as well as the surface. Default: true.
// showdots = If true, shows the calculated surface vertices. Default: false.
// showpatch = If true, shows the surface faces. Default: true.
// size = Size to show control points and lines. // size = Size to show control points and lines.
// style = The style of subdividing the quads into faces. Valid options are "default", "alt", and "quincunx".
// convexity = Max number of times a line could intersect a wall of the shape.
// Example: // Example:
// patch1 = [ // patch1 = [
// [[15,15,0], [33, 0, 0], [ 67, 0, 0], [ 85, 15,0]], // [[15,15,0], [33, 0, 0], [ 67, 0, 0], [ 85, 15,0]],
@ -999,32 +1007,39 @@ module bezier_polyhedron(patches=[], splinesteps=16, vnf=EMPTY_VNF, style="defau
// [[15,85,0], [33,100, 0], [ 67,100, 0], [ 85, 85,0]], // [[15,85,0], [33,100, 0], [ 67,100, 0], [ 85, 85,0]],
// ]; // ];
// trace_bezier_patches(patches=[patch1, patch2], splinesteps=8, showcps=true); // trace_bezier_patches(patches=[patch1, patch2], splinesteps=8, showcps=true);
module trace_bezier_patches(patches=[], size=1, showcps=false, splinesteps=16, showpatch=true, showdots=true) module trace_bezier_patches(patches=[], size, splinesteps=16, showcps=true, showdots=false, showpatch=true, convexity=10, style="default")
{ {
if (showcps) { if (showcps || showdots) {
for (patch = patches) { for (patch = patches) {
move_copies(flatten(patch)) color("red") sphere(d=size*2); bounds = pointlist_bounds(flatten(patch));
color("cyan") size = default(size, max(bounds[1]-bounds[0])*0.01);
if (is_tripatch(patch)) { echo(size=size);
for (i=[0:1:len(patch)-2], j=[0:1:len(patch[i])-2]) { if (showcps) {
extrude_from_to(patch[i][j], patch[i+1][j]) circle(d=size); move_copies(flatten(patch)) color("red") sphere(d=size*2);
extrude_from_to(patch[i][j], patch[i][j+1]) circle(d=size); color("cyan") {
extrude_from_to(patch[i+1][j], patch[i][j+1]) circle(d=size); if (is_tripatch(patch)) {
} for (i=[0:1:len(patch)-2], j=[0:1:len(patch[i])-2]) {
} else { extrude_from_to(patch[i][j], patch[i+1][j]) circle(d=size);
for (i=[0:1:len(patch)-1], j=[0:1:len(patch[i])-1]) { extrude_from_to(patch[i][j], patch[i][j+1]) circle(d=size);
if (i<len(patch)-1) extrude_from_to(patch[i][j], patch[i+1][j]) circle(d=size); extrude_from_to(patch[i+1][j], patch[i][j+1]) circle(d=size);
if (j<len(patch[i])-1) extrude_from_to(patch[i][j], patch[i][j+1]) circle(d=size); }
} else {
for (i=[0:1:len(patch)-1], j=[0:1:len(patch[i])-1]) {
if (i<len(patch)-1) extrude_from_to(patch[i][j], patch[i+1][j]) circle(d=size);
if (j<len(patch[i])-1) extrude_from_to(patch[i][j], patch[i][j+1]) circle(d=size);
}
}
} }
} }
if (showdots){ if (showdots){
vnf = bezier_patch(patch, splinesteps=splinesteps); vnf = bezier_patch(patch, splinesteps=splinesteps, style=style);
color("blue") move_copies(vnf[0]) sphere(d=size); color("blue") move_copies(vnf[0]) sphere(d=size);
} }
} }
} }
if (showpatch) if (showpatch) {
bezier_polyhedron(patches=patches, splinesteps=splinesteps); bezier_polyhedron(patches=patches, splinesteps=splinesteps, convexity=convexity, style=style);
}
} }

View file

@ -8,7 +8,7 @@
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
BOSL_VERSION = [2,0,234]; BOSL_VERSION = [2,0,235];
// Section: BOSL Library Version Functions // Section: BOSL Library Version Functions