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

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)

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?

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

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?

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…:confused:

Sam

There is this wonderful lib of utilities that I came across awhile back and have integrated into our pipeline.

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

great thanks snolan. will check these out

Sam

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

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