Results 1 to 9 of 9

Thread: using api setPoints method()

  1. #1
    variable
    Join Date
    Feb 2016
    Posts
    16

    Default using api setPoints method()



    Hello i have my script almost working now. except the very last part where i set the points on my mesh.

    Basically i have a script in python API which gets the points from 3 different shaped sphere meshes, finds the difference between meshes 2 and 3, adds the difference to the points of mesh 1, and finally sets mesh 1 to this new shape

    I have tried to track the result of things at each step throughout the script and it seems the result of the difference added to the original mesh values are fine. But then when i use setPoints(), my mesh explodes!

    i dont know why because the set points works fine when i simply copy one set of verts straight onto a mesh, but when i add together points and then setPoints i think i have created a problem

    I have in included the code, im sorry its a bit long, but i think pretty straightforward, if anyone can help my make this work then you would really be helping me out.


    thanks alot,
    Sam

    Code:
    import maya.OpenMaya as om
       
    
    def getPoints(geo):
    
        sel = om.MSelectionList()
        dag = om.MDagPath()
       
        sel.add(geo)
        sel.getDagPath(0,dag)
      
        mesh = om.MFnMesh(dag)
      
        vts=om.MFloatPointArray()
        mesh.getPoints(vts, om.MSpace.kObject)
       
        return mesh,vts
    
     
    def findDiff(scan1_verts, scan2_verts):
        diff_list=om.MFloatPointArray()
        counter=0
        for i in xrange(scan1_verts.length()):    
            p1 = scan1_verts[i]
            p2 = scan2_verts[i] 
            diff_list.append(om.MFloatPoint(p2)-om.MFloatVector(p1))
    
    	return diff_list	
    
    def addDiff(diff_list, target_mesh_verts):
        final_list=om.MFloatPointArray()
        for i in xrange(target_mesh_verts.length()):
            p1 = target_mesh_verts[i]
            p2 = diff_list[i]
            final_list.append(om.MFloatPoint(p1)+om.MFloatVector(p2))
    
        return final_list
    
    def setPoints(geo, finalPos):	
        geo.setPoints(finalPos, om.MSpace.kObject) 
    
    
    #store the vert positions for each mesh
    mFnMeshTarget, target_mesh_verts = getPoints("target")
    mFnMesh, scan1_verts = getPoints("neutral")
    mFnMesh2, scan2_verts = getPoints("expression")
    
    #find the difference between the verts from the expression scan and neutral scan 
    diffList = findDiff(scan1_verts,scan2_verts)
    
    finalPos = addDiff(diffList, target_mesh_verts)
    
    #set the mesh difference to the target mesh
    setPoints(mFnMeshTarget,finalPos)

  2. #2
    program Theodox's Avatar
    Join Date
    Mar 2012
    Location
    Seattle
    Posts
    1,104

    Default

    hard to know without seeing before and after conditions. It looks like you're expecting the two meshes to have the same vert ordering? Is that true?

    Other possibilities
    1) Are you sure you know what units you are using? The points are just tuples of numbers ... but internally Maya always uses centimeters. You need to use MDistance.internalToUI() or MDistance.UiToInternal() to go back and forth between the visible units and the the internal ones.
    2) Same thing for spaces: You'll need to use the (space = MSpace.KWorld) argument to get all of the units in consistent spacing both for getting and setting
    3) Are you calling UpdateSurface() at the end?

  3. #3
    variable
    Join Date
    Feb 2016
    Posts
    16

    Default

    thanks Theodox,

    yea, imagine you just take a sphere and duplicate it 3 times (so identical topology), position them in a line and deform them a bit. so when i transfer the vertex positions i want them to be applied in local space to the sphere 1, not world space. kind of like setting up a blend shape head.

    1) i didnt know i had to be that specific about the units, though at the moment i just want the sphere to not explode in a thousand different directions, so i will deal with scale later
    2) i thought using MSpace.kObject would be the correct argument for what i need?
    3) im not using UpdateSurface(), is this needed?, it seems to be changing the spheres points when i call setPoints, so is this necessary?

    thanks,
    Sam

  4. #4
    program Theodox's Avatar
    Join Date
    Mar 2012
    Location
    Seattle
    Posts
    1,104

    Default

    It depends a bit - a lot of this stuff behaves oddly outside of plugins, which is very unfortunate. Is this just a script? or in an MPXCommand?

  5. #5
    variable
    Join Date
    Feb 2016
    Posts
    16

    Default

    this is just a script run from script editor. I just needed api because my meshes will eventually be very big. This is the only thing that i will need to use API for though, so i thought it was worth getting it working.

    People helping me from a previous problem said to switch everything to API2 because its better for this. But i barely understand what im doing with normal api...:/

    Sam

  6. #6

    Default

    There is this wonderful lib of utilities that I came across awhile back and have integrated into our pipeline.
    https://github.com/bungnoid/glTools/.../utils/mesh.py

    Take a look at the getPoints() and setPoints() functions. I think you might find these as well as some others there of help.
    -Sean

  7. #7
    variable
    Join Date
    Feb 2016
    Posts
    16

    Default

    great thanks snolan. will check these out

    Sam

  8. #8
    variable
    Join Date
    Feb 2016
    Posts
    16

    Default

    im not even sure if the 'findDiff' is returning an array in the first place. When i print the result of 'findDiff' it just prints one set of coordinates:

    #for x in xrange(diffList.length()):
    # print diffList[x][0],diffList[x][1],diffList[x][2]

    #result:
    0.0 0.0 0.0246293283999

    am i not assigning values to the MFloatPointArray properly?

    Sam

  9. #9

    Default

    isn't what you're trying to achieve can be done by blendShape nodes? you want to do:

    output = mesh1+(mesh3-mesh2)

    .. or otherwise
    output = mesh1+mesh3-mesh2

    blend shape is a bit weird from the point that:
    output = baseMesh+[ (shape-baseMesh)*weight for each shape mesh]

    ..so.. you just do this:
    create a "base mesh" where all verts are at (0,0,0), add a blend shape with mesh1, 2, 3 as blend targets,

    then it's simply:
    mesh1 has weight 1.0
    mesh2 has weight -1.0
    mesh3 has weight 1.0

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •