Home Technical Talk

[MaxScript] Spacing/Distributing a sorted Vertexloop? [3ds max][SOLVED]

polycounter lvl 4
Offline / Send Message
Pinned
LandeTLS polycounter lvl 4
Hi, iwe been struggling with a somewhat geometry math related situation.
I got such good help here last time i asked a question so i thought id ask another.
I tried searching through the forums but i couldnt find a similar working solution for maxscript.

So the main goal is to basically replicate the looptools->space function in graphitemodelingtools (3ds max) in maxscript.

I already wrote a function some time ago that gives me arrays of sorted vertex loops from edgeloop selections.
Sorted as in for an open loop the first array index is the first vert on the edgeloop, second index is the second vert in the edgeloop and so on.

But im at a loss about how to determine the new positions for the verts.

I got as far as determining the total length of the edgeloop by using PolyOp.GetVert to get vert position.
Then adding to the distance via distance "last vertex position" "vertex postion".
Then getting the even distance between each vert by dividing with the amount of verts in the set.
The issue now is that how do i determine the actual new worldspace position each vertex should get along the loop.

unfinished code snippet:
Note the AspDev.GetVertPosition/AspDev.SetVertPosition are just wrappers for polyop.GetVert/SetVert.

for vertSet in sortedVertSets do
    (
        local vertCount = vertSet.count

        local loopLength = 0
        local pvPos
        --finish calls to getVertPosition
        local vPosArray = for vert in vertSet collect
        (
            vPos = AspDev.GetVertPosition modOrObj vert node:node
            if classOf pvPos == point3 do loopLength += (distance pvPos vPos)
            --store last vPos
            pvPos = vPos
            --finally collect current vPos to vPosarray
            vPos
        )
        local pointA = vPosArray[1]
        local pointB = vPosArray[vertCount]
        --this should have the correct spacing distance??
        local loopSpacing = loopLength / vertCount

       --what now?

        --batch setVert op
        AspDev.SetVertPosition modOrObj vertSet vPosArray node:node
    )


Thanks in advance

Replies

  • LandeTLS
    Options
    Offline / Send Message
    LandeTLS polycounter lvl 4
    After some more research i have found that the solution is even more complex than i had first assumed.

    The method i had first invisioned would be translating each vert "forward" if the edgeloop is curved.
    i would only get expected even spacing on a completly straight loop. But would result in the last edge being shorter in a curved edgeloop.

    It seems to me that i will need to use an interpolation curve created by using the vertex positions as curve points. And then getting even points along the resulting curve to get proper spacing of the edgeloop. 

    I Started by testing with creating a smooth max spline object from the edgeloop verts and then using interpSpline3D to get even points along the spline. This works but the resulting interpolation is very smooth, and creates way too much displacement in most cases. 

    I tried using both a line curve (no smoothing). But it really shrinks the changes the loop too much.
    a CVCurve with a lower interpolation order might work. But getting the creation via maxscript api working is really clumpsy and difficult. Its also very slow. 

    Im thinking right now that the only real way is by implimenting a catmull-rom curve interpolation(or similar) function. Anybody got any hints on doing this in maxscript by building via an array of point3. And returing an array of evenly spaced point3?
  • kio
    Options
    Online / Send Message
    kio polycounter lvl 16
    http://paulbourke.net/miscellaneous/interpolation/

    maybe just drop in some interpolation function and sample it the desired steps?
  • LandeTLS
    Options
    Offline / Send Message
    LandeTLS polycounter lvl 4
    kio said:
    http://paulbourke.net/miscellaneous/interpolation/

    maybe just drop in some interpolation function and sample it the desired steps?
    Yes. Thats my best guess too. Iwe been looking at these types of interpolation functions all day. But i cant wrap my head around how to convert these to support an arbitary amount of points. Most appear to be based around being passed 2 or 4 points.
    Keep in mind that im not very knowledgable about math equations.
    Thanks for the link btw. Had not seen these exact implimentations before. 

    Im imagining building a mxs struct that builds and caches the interpolation curve from the points. Can then be called to evaluate a point along the curve. Kindof like the animationCurve class in unity3D. I know this kindof thing would be much faster if implimented in c++ or even dotnet. But im trying to stick to pure mxs for this project for simplicity.
  • poopipe
    Options
    Offline / Send Message
    poopipe grand marshal polycounter
    you could try generating a bezier curve that gets it's tangents from vectors that are perpendicular to the bisector of each vert along the loop .
    I'm not sure how different that'd be from a standard smooth curve by default but I imagine you could weight it by edge length or something. 


  • monster
    Options
    Offline / Send Message
    monster polycounter
    You tried converting positions to a Smooth spline, but it had too much overshoot.

    Maybe try creating an animation curve instead. The auto tangents prevent overshoot. Then convert the trajectory to a max spline,  then use interpCurve3D to get a position on the path.
  • LandeTLS
    Options
    Offline / Send Message
    LandeTLS polycounter lvl 4
    Ok i solved it with some help from a cgsociety user. 

    He provided me with a simple interpolation method that factored in each changed position in the spacing in addition to total length. 
Sign In or Register to comment.