Home Technical Talk

MaxScript - Projections?

interpolator
Offline / Send Message
DEElekgolo interpolator
So I was trying to see if I can distort some geometry using some sort of equation using max script. Spherical projections would work for nearly every type of geometry so I tried using Stereographic Projection.
And emulated the equation in max script.
85e103ce8a481c20342f4bd738c63ee9.png
rollout projectRollout "Project"
(
    button projectbtn "Project"
    on projectbtn pressed do
    (
        convertTo $ PolyMeshObject
        modPanel.addModToSelection (Edit_Poly ()) ui:on
        obj = $
        subobjectLevel = 1
        modPanel.setCurrentObject $.modifiers[#Edit_Poly]
        for i = 1 to obj.GetNumVertices() do
        (
            print(obj.GetVertex i)
            vert = obj.GetVertex i
            
            x = vert.x/1 - vertz
            y = vert.y/1 - vertz
            z = 0
            
            newvert = [x,y,z]
            print newvert
            polyop.setVert obj i newvert
        )
        update obj
    )
)
createdialog projectRollout
I tried to do it in 3d space rather then 2d space in max script and got this error.
2010-02-15_2227.png
Should I be doing something like this in UV space? I would think that having the Z be 0 would still give me the same effect. And if I was to have it be in UV space, how would I go about converting UV space geometry into 3D space like how textools does it?

Replies

  • renderhjs
    Options
    Offline / Send Message
    renderhjs sublime tool
    x = vert.x / 1.0 - vertz;
    
    are you sure that vertz is a existing variable?, also make sure that you work with floats as soon as you try to divide or multiply stuff.
  • SyncViewS
    Options
    Offline / Send Message
    SyncViewS polycounter lvl 13
    Hi, I don't know exactly what's the purpose of this script, anyway I spotted a couple of issues
    x = vert.x/1 - vertz
                y = vert.y/1 - vertz
    
    should be
    
                x = vert.x/1 - vert.z
                y = vert.y/1 - vert.z
    

    You may want to add a "with redraw off" context to speed things up and "with undo on" to reduce program granularity.
  • DEElekgolo
    Options
    Offline / Send Message
    DEElekgolo interpolator
    Thanks! I got it working. Also when it said 1-z it actually meant to invert it. Here is what I get now.
    2010-02-16_0008.png
    But some of the meshes really mess up when it attempts to move a vertice to 30 different locations. Is there a way to split these vertices when this happens? Or a way to make each faces its own element?
  • SyncViewS
    Options
    Offline / Send Message
    SyncViewS polycounter lvl 13
    Good! For the sake of optimization if you plan to use it on large objects, you could store calculated positions x, y and z in an Array of Point3, then shift the whole vertexes in a single step with polyOp.moveVerts, it would be much faster.

    Something like:
            local iNumVerts = obj.getNumVertices()
            local ap3Shift = #()
            ap3shift[iNumVerts] = [0,0,0]
    
            for i = 1 to iNumVerts do
            (
                vert = obj.GetVertex i
                -- print vert
                
                ap3Shift[i].x = (vert.x/1 - vert.z) - vert.x
                ap3Shift[i].y = (vert.y/1 - vert.z) - vert.y
                ap3Shift[i].z = -vert.z
                
                -- print ap3Shift[i]
            )
            polyOp.moveVert obj #{1..iNumVerts} ap3Shift
    

    It's not tested but should work, at least give you an idea.
  • MoP
    Options
    Offline / Send Message
    MoP polycounter lvl 18
    SyncViewS: That's a pretty neat optimisation, I didn't really know about that. Might try it on some of my scripts, see if they get faster :)
  • SyncViewS
    Options
    Offline / Send Message
    SyncViewS polycounter lvl 13
    Hi MoP, that's way faster than shifting every single vertex. polyOp.moveVert was introduced by Larry Minton with AVGuard dlx as addon for 3ds Max 9, and included as standard dlx from version 2008. If it wasn't for this nice method, I would have never been able to code any of my paint deform tools, because they would have been unacceptably slow.

    Another optimization trick is with polyOp methods aliases. I don't know if it is the same for GetVertex, but some of these functions actually are slow and lead to memory leaks/bloat. Functions aliases solve the issue:
    -- Standard (no good for memory / speed)
    local p3VertPos = polyOp.getVert theEditablePoly iVert
    
    -- With function alias (faster and memory safe)
    local gv = polyOp.getVert
    local p3VertPos = gv theEditablePoly iVert
    

    I experienced this issue with almost all methods which actually query the geometry database for some information, like get vertex position and get face normal or center.
  • CrazyButcher
    Options
    Offline / Send Message
    CrazyButcher polycounter lvl 18
    -- shouldn't this:
    x = vert.x/1 - vert.z
    y = vert.y/1 - vert.z
    
    --be actually
    x = vert.x/(1 - vert.z)
    y = vert.y/(1 - vert.z)
    

    as divisions/mul come first in math, but the equation presented is different
  • SyncViewS
    Options
    Offline / Send Message
    SyncViewS polycounter lvl 13
    Hey CrazyButcher, I didn't look at the equation assuming the code was right, but the exact math is yours, with no doubt.
Sign In or Register to comment.