…or a combination of these. I like this one better
macroscript subDSpline
category:"splineTools"
tooltip:"subDSpline"
(
try(DestroyDialog divideSpline)catch()
rollout divideSpline "subDSpline" width:244 height:32
(
spinner spn1 "" type:#integer pos:[8,8] width:50 height:16 across:5 range:[1,1000,0]
checkbox linear "smooth" checked:false offset:[8,4]
checkbox closeSpline "o" checked:false offset:[25,4]
button btnOK "ok" align:#right
button btnCancel "cancel" align:#right offset:[6,0]
local spline, oSpline
fn setLinear state=
(
if (spline!=undefined) do
(
if state==off then
(
for i = 1 to (numknots spline) do
(
setKnotType spline 1 i #corner
updateShape spline
)
)
else
(
for i = 1 to (numknots spline) do
(
setKnotType spline 1 i #smooth
updateShape spline
)
)
)
)
fn clSpline=
(
if ((spline!=undefined) and (closeSpline.checked==true)) do (close spline 1; updateShape spline)
)
fn subDSpline tSpline count=
(
cLength = curveLength tSpline
interp = (cLength/count)/cLength
spline = splineShape name:"sp" wirecolor:green
spline.vertexticks = on
addnewSpline spline
for i = 0 to count do
(
pos = interpCurve3D tSpline 1 (interp*i) pathParam:false
addKnot spline 1 #corner #curve pos
)
setLinear linear.checked
clSpline()
updateShape spline
)
on divideSpline open do
(
if ($!=undefined) do
(
max create mode
oSpline = $
-- hide oSpline
)
)
on spn1 buttondown do
(
)
on spn1 buttonup do
(
if (spline!=undefined and not spline.isdeleted) do spline.vertexticks = off
)
on spn1 changed val do
(
if (oSpline!=undefined) do
(
if (spline!=undefined and not spline.isdeleted) do delete spline
subDSpline oSpline val
)
)
on btnOK pressed do
(
if (spline!=undefined) do
(
select spline
spline.wirecolor = gray
delete oSpline
spline = undefined
)
DestroyDialog divideSpline
)
on btnCancel pressed do
(
if (spline!=undefined) do
(
delete spline
spline = undefined
unhide oSpline
)
DestroyDialog divideSpline
)
on linear changed state do
(
setLinear state
)
on closeSpline changed state do
(
clSpline()
)
)
if $!=undefined do CreateDialog divideSpline style:#(#style_toolwindow) modal:false
)
after I show my solution some people will say: ‘Sure! It’s so easy. I just didn’t want to waste my time…”
Well but some years ago I spent couple days to find this solution. And believe me, it’s not trivial.
OK. theres is the code:
/* test spline */
with redraw off
(
delete objects
global sp = splineShape name:"sp" wirecolor:orange
sp.vertexticks = on
addnewSpline sp
addKnot sp 1 #corner #curve [0,0,0]
addKnot sp 1 #corner #curve [100,0,0]
setknottype sp 1 1 #bezierCorner
setoutvec sp 1 1 [0,40,0]
updateShape sp
)
/* the subdivide function */
fn subdivideSplineEvenly sp index divisions:1 = if iskindof sp SplineShape do
(
converttosplineshape sp
step = 1./(divisions+1)
for k=1 to divisions do
(
param = k*step
p = lengthToPathParam sp index param
segs = numSegments sp index
seg = floor(p*segs) + 1
ps = p*segs - seg + 1
k = refineSegment sp index seg ps
resetLengthInterp()
)
updateshape sp
)
/* go the test >evenly subdivide 5 times... */
(
subdivideSplineEvenly sp 1 divisions:5
)
because I didn’t see real interest in this issue, I don’t give any comments and explanation. [b][i]sapienti sat
[/i][/b]
i purposely left some imperfection in my code… could anyone point it out?
Denis, I didn’t have time to dive into your code yet, but from a small experiment that I did with it, it looks like it doesn’t work very well with big numbers.
with divisions = 20 you I can already see the imperfection, and when the numbers are bigger, like divisions = 50 it is obvious.
Am I missing something here?
Edit:
oh, now I see your comment
the first problem was found… so we can add extra parameter to set the number of length interpolation steps… new function has to look:
fn subdivideSplineEvenly sp index divisions:1 steps:100 = if iskindof sp SplineShape do
(
converttosplineshape sp
step = 1./(divisions+1)
for k=1 to divisions do
(
param = k*step
p = lengthToPathParam sp index param steps:steps
segs = numSegments sp index
seg = floor(p*segs) + 1
ps = p*segs - seg + 1
k = refineSegment sp index seg ps
resetLengthInterp()
)
updateshape sp
)
/*
-- try it
subdivideSplineEvenly sp 1 divisions:50 steps:10000
*/
but this is not the only one problem …
yesterday, I tried a complicated method,
that for a momment made me think I was close… but no.
I grunted, deleted my attempt, and emptied the recycle bin…
the next has something I thought away from the computer, last night
but I wasn’t considering ‘resetlengthInterp’,
so it would have never worked without seeing denisT code
(still I havent analysed denisT code, yet)
(
fn divideEven o s segs steps: =
(
convertToSplineShape o
if steps==unsupplied do steps = curveLength o * 5 as integer
for n = 1. to segs - 1 do if not keyboard.escPressed do
(
pa = lengthToPathParam o (n/segs) steps:steps
pa-= 1./n*(n-1)
pa*= n
refineSegment o s n pa
resetLengthInterp o
)
updateShape o
)
divideEven $ 1 28
)
I don’t know if it is good enough… but seems to work
i see that you always refine next segment. for multi-segment spline it’s not always true.
let me check, I used your demo in other post…
but if the spline already has segments, you get non even segments. right?
Right. But at least we have cuts in the right places. It’s a different story what to do with old knots. We will decide it later.
usually i make an arbitrary sample. so working on a function you always have to keep in mind its general usage.
yeap, that would be the best case, but because of the hurry,
and lack of inborn geniality… :]
.
here’s my second ver. it now allows existing verts:
(
fn divideEven o s segs steps: =
(
convertToSplineShape o
if steps==unsupplied do steps = curveLength o s * 5 as integer
for n = 1. to segs - 1 do
(
pa = lengthToPathParam o s (n/segs) steps:steps
prevseg = (FindPathSegAndParam o s pa)[1] - 1
--prevseg = (ceil (pa / (1./(numSegments o s)))) - 1
pa = pa /(1.0/(numSegments o s)) - prevseg
refineSegment o s (prevseg + 1) pa
resetLengthInterp o
)
updateShape o
)
divideEven $ 1 22
)
ok… when we have the method we can think about old (original) knots…
what a criterion could be to simply delete a knot?
find the crossing point defined by the 2 adjacent tangents
and move those tangents to 0.5 distance to the cross point…
hmm… it’s not clear for me. again. we are looking for some rules. why some point on spline can be reduced?