Skip to content

Commit 2f95b3b

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 601cd1c + 6a84788 commit 2f95b3b

2 files changed

Lines changed: 65 additions & 50 deletions

File tree

nurbs.scad

Lines changed: 64 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -277,55 +277,65 @@ function nurbs_curve(control,degree,splinesteps,u, mult,weights,type="clamped",
277277
_extend_knot_vector(xknots,0,len(control)+degree+1),
278278
bound = type=="clamped" ? undef
279279
: [knot[degree], knot[len(control)]],
280-
adjusted_u = !is_undef(splinesteps) ?
281-
[for(i=[degree:1:len(control)-1])
282-
each
283-
if (!approx(knot[i],knot[i+1]))
284-
lerpn(knot[i],knot[i+1],splinesteps, endpoint=false),
285-
if (type!="closed") knot[len(control)]
286-
]
287-
: is_undef(bound) ? u
288-
: add_scalar((bound[1]-bound[0])*u,bound[0])
289-
)
290-
uniform?
291-
let(
292-
msum = cumsum(mult)
293-
)
294-
[for(uval=adjusted_u)
295-
let(
296-
mind = floor(uval*(len(mult)-1)),
297-
knotidxR=msum[mind]-1,
298-
knotidx = knotidxR<len(control) ? knotidxR : knotidxR - mult[mind]
299-
)
300-
_nurbs_pt(knot,select(control,knotidx-degree,knotidx),uval,1,degree,knotidx)
301-
]
302-
: let(
303-
kmult = _calc_mult(knot),
304-
knotidx =
305-
[for(
306-
kind = kmult[0]-1,
307-
uind=0,
308-
kmultind=1,
309-
output=undef,
310-
done=false
311-
;
312-
!done
313-
;
314-
output = (uind<len(adjusted_u) && approx(adjusted_u[uind],knot[kind]) && kind>kmult[0]-1 && ((kmultind>=len(kmult)-1 || kind+kmult[kmultind]>=len(control))))
315-
?kind-kmult[kmultind-1]
316-
: (uind<len(adjusted_u) && adjusted_u[uind]>=knot[kind] && adjusted_u[uind]>=knot[kind] && adjusted_u[uind]<knot[kind+kmult[kmultind]]) ? kind
317-
: undef,
318-
done = uind==len(adjusted_u),
319-
uind = is_def(output) ? uind+1 : uind,
320-
inc_k = uind<len(adjusted_u) && adjusted_u[uind]>=knot[kind+kmult[kmultind]],
321-
kind = inc_k ? kind+kmult[kmultind] : kind,
322-
kmultind = inc_k ? kmultind+1 : kmultind
323-
)
324-
if (is_def(output)) output]
280+
adjusted_u_orig = !is_undef(splinesteps) ?
281+
[for(i=[degree:1:len(control)-1])
282+
each
283+
if (!approx(knot[i],knot[i+1]))
284+
lerpn(knot[i],knot[i+1],splinesteps, endpoint=false),
285+
if (type!="closed") knot[len(control)]
286+
]
287+
: is_undef(bound) ? u
288+
: add_scalar((bound[1]-bound[0])*u,bound[0]),
289+
reorder = is_undef(splinesteps) && !is_increasing(adjusted_u_orig) ?
290+
let(ind = sortidx(adjusted_u_orig))
291+
[ind,sortidx(ind)]
292+
: false,
293+
// The u list needs to be sorted for the algorithm to identify the knot spans, so sort it if necessary
294+
adjusted_u = reorder ? select(adjusted_u_orig,reorder[0]) : adjusted_u_orig,
295+
nurbs_pts =
296+
uniform?
297+
let(
298+
msum = cumsum(mult)
299+
)
300+
[for(uval=adjusted_u)
301+
let(
302+
mind = floor(uval*(len(mult)-1)),
303+
knotidxR=msum[mind]-1,
304+
knotidx = knotidxR<len(control) ? knotidxR : knotidxR - mult[mind]
305+
)
306+
_nurbs_pt(knot,select(control,knotidx-degree,knotidx),uval,1,degree,knotidx)
307+
]
308+
: let(
309+
kmult = _calc_mult(knot),
310+
knotidx =
311+
[for(
312+
kind = kmult[0]-1,
313+
uind=0,
314+
kmultind=1,
315+
output=undef,
316+
done=false
317+
;
318+
!done
319+
;
320+
output = (uind<len(adjusted_u) && approx(adjusted_u[uind],knot[kind]) && kind>kmult[0]-1
321+
&& ((kmultind>=len(kmult)-1 || kind+kmult[kmultind]>=len(control))))
322+
?kind-kmult[kmultind-1]
323+
: (uind<len(adjusted_u) && adjusted_u[uind]>=knot[kind] && adjusted_u[uind]>=knot[kind]
324+
&& adjusted_u[uind]<knot[kind+kmult[kmultind]]) ? kind
325+
: undef,
326+
done = uind==len(adjusted_u),
327+
uind = is_def(output) ? uind+1 : uind,
328+
inc_k = uind<len(adjusted_u) && adjusted_u[uind]>=knot[kind+kmult[kmultind]],
329+
kind = inc_k ? kind+kmult[kmultind] : kind,
330+
kmultind = inc_k ? kmultind+1 : kmultind
331+
)
332+
if (is_def(output)) output]
333+
)
334+
[for(i=idx(adjusted_u))
335+
_nurbs_pt(knot,slice(control, knotidx[i]-degree,knotidx[i]), adjusted_u[i], 1, degree, knotidx[i])
336+
]
325337
)
326-
[for(i=idx(adjusted_u))
327-
_nurbs_pt(knot,slice(control, knotidx[i]-degree,knotidx[i]), adjusted_u[i], 1, degree, knotidx[i])
328-
];
338+
reorder ? select(nurbs_pts,reorder[1]) : nurbs_pts;
329339

330340

331341
function _nurbs_pt(knot, control, u, r, p, k) =
@@ -559,7 +569,7 @@ function nurbs_patch_points(patch, degree, splinesteps, u, v, weights, type=["cl
559569
// Usage: (as a function)
560570
// vnf = nurbs_vnf(patch, degree, [splinesteps], [mult=], [knots=], [weights=], [type=], [style=], [reverse=], [triangulate=], [caps=], [caps1=], [caps2=]);
561571
// Usage: (as a module)
562-
// nurbs_vnf(patch, degree, [splinesteps], [mult=], [knots=], [weights=], [type=], [style=], [reverse=], [triangulate=], [caps=], [caps1=], [caps2=], [convexity=],[atype=],[cp=],...) CHILDREN;
572+
// nurbs_vnf(patch, degree, [splinesteps], [mult=], [knots=], [weights=], [type=], [style=], [reverse=], [triangulate=], [caps=], [caps1=], [caps2=], [convexity=],[atype=],[cp=], [cp=], [atype=], ...) CHILDREN;
563573
// Description:
564574
// Compute a (possibly non-manifold) VNF for a NURBS. The input patch must be an array of control points or a NURBS parameter list. If weights is given it
565575
// must be an array of weights that matches the size of the control points. The style parameter
@@ -583,6 +593,11 @@ function nurbs_patch_points(patch, degree, splinesteps, u, v, weights, type=["cl
583593
// reverse = If true, reverse all face normals.
584594
// style = {{vnf_vertex_array ()}} style to use for triangulating the surface. Default: "default"
585595
// triangulate = If true, triangulates endcaps to resolve possible CGAL issues. This can be an expensive operation if the endcaps are complex. Default: false
596+
// 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"
597+
// anchor = (module) Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `"origin"`
598+
// spin = (module) Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
599+
// orient = (module) Vector to rotate top toward, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
600+
// atype = (module) Select "hull" or "intersect" anchor type. Default: "hull"
586601
// Example(3D): Quadratic B-spline surface
587602
// patch = [
588603
// [[-50, 50, 0], [-16, 50, 20], [ 16, 50, 20], [50, 50, 0]],

version.scad

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ _BOSL2_VERSION = is_undef(_BOSL2_STD) && (is_undef(BOSL2_NO_STD_WARNING) || !BOS
1313
echo("Warning: version.scad included without std.scad; dependencies may be missing\nSet BOSL2_NO_STD_WARNING = true to mute this warning.") true : true;
1414

1515

16-
BOSL_VERSION = [2,0,736];
16+
BOSL_VERSION = [2,0,737];
1717

1818

1919
// Section: BOSL Library Version Functions

0 commit comments

Comments
 (0)