noob methods for working with API wrappers

321 views
Skip to first unread message

pjrich

unread,
Feb 21, 2010, 2:57:19 PM2/21/10
to python_inside_maya
I'm using a python wrapper of fnMesh.allIntersections, which uses a
number of other wrappers including MFloatPointArray() -- when I try to
get the contents of the array I only get a pointer to the array's
wrapper (I think):

<maya.OpenMaya.MFloatPointArray; proxy of <Swig Object of type
'MFloatPointArray *' at 0x23fed220> >

I don't know enough about the API to use MFloatPointArray.get(), I get
errors like:

# NotImplementedError: Wrong number of arguments for overloaded
function 'MFloatPointArray_get'.
# Possible C/C++ prototypes are:
# get(float [][4])
# get(double [][4])

Is there an easy way to get these kinds of values with pymel, or to
work with these wrappers in general, besides learning C++? The Maya
API docs all seem to assume I already know it.

pjrich

unread,
Feb 21, 2010, 6:52:54 PM2/21/10
to python_inside_maya
So far I've been able to extract the data through a roundabout method,
but I don't have confidence in the result. I'm trying to find the
points in space where a ray intersects a mesh, but though it's in
world space and the ray should be passing all the way through the
object I'm apparently only getting 1 intersection at (0,0,0). I can
set it to "direction = Both" but in that case hitRayParams, which
should return the distance, shows two intersections at the same
distance, which I believe means it's just hitting both sides of the
same polygon.

hitPoints = om.MFloatPointArray()
hit = fnMesh.allIntersections(raySource, rayDir, faceIds, triIds,
idsSorted, worldSpace, maxParam, testBothDirections, accelParams,
sortHits, hitPoints, hitRayParams, hitFaces, hitTris, hitBarys1,
hitBarys2, tolerance)
hitPointsList = [om.MFloatPoint() for i in range(hitPoints.length())]
for x in hitPointsList:
print "hitpoint:", x[0], x[1], x[2], x[3]

So how do I get all the intersections in world space?

Thanks,
p

pjrich

unread,
Feb 21, 2010, 9:27:18 PM2/21/10
to python_inside_maya
Just found Jason Osipa's half-started
http://docs.osipaentertainment.com/Maya_API_Python_Attribute_and_Type_Reference
which suggests there isn't an easy way, but I also found his oeRay.py
which is a plugin-ified version of closestIntersection, which is very
similar to the function I'm interested in... so I think I have a good
idea of how to do it the hard way if no easy way exists, by which I
mainly mean PyMEL.

But I'd still love to know if there's an easy way.

Cheers,
P

johnvdz

unread,
Feb 22, 2010, 12:08:28 AM2/22/10
to python_in...@googlegroups.com
Hi all,

i was wanting to make my own Node that stored Vertex Offset data sorta in the same structure as a PolyTweak node does. but i want to feed it the offset data.

so that i can just acumulate offsets by creating more DeformerNodes and assigning offset data.

my question is is what data Type am i looking for to do this. i'm fairly new to API and at the moment all i have done is used it to get and set data note create my own node and set its data. Yet!!


i have been looking at the ytwistNode example in the Maya Help(example below).

i think all i need to know is get the right DataStorage in the

while geomIter.isDone() == False:

but what is the data block i should be looking for? is there a section on setting and storing data to a node?

any help would be great.

john


class yTwistNode(OpenMayaMPx.MPxDeformerNode):
# class variables
angle = OpenMaya.MObject()
# constructor
def __init__(self):
OpenMayaMPx.MPxDeformerNode.__init__(self)
# deform
def deform(self,dataBlock,geomIter,matrix,multiIndex):
#
# get the angle from the datablock
angleHandle = dataBlock.inputValue( self.angle )
angleValue = angleHandle.asDouble()
#
# get the envelope
envelope = OpenMayaMPx.cvar.MPxDeformerNode_envelope
envelopeHandle = dataBlock.inputValue( envelope )
envelopeValue = envelopeHandle.asFloat()
#
# iterate over the object and change the angle
while geomIter.isDone() == False:
point = geomIter.position()
ff = angleValue * point.y * envelopeValue
if ff != 0.0:
cct= math.cos(ff)
cst= math.sin(ff)
tt= point.x*cct-point.z*cst
point.z= point.x*cst + point.z*cct
point.x=tt
geomIter.setPosition( point )
geomIter.next()

pjrich

unread,
Feb 23, 2010, 12:29:40 AM2/23/10
to python_inside_maya
Hi all, so far I've learned a lot going through the archives -- I'm
trying to leave a paper trail so anyone who comes after me will have
an easier time of it. Apparently about a year ago Jason Osipa came
through with similar questions, his experience has been very valuable
for me.

I'm still curious about easy and standardized ways of getting and
setting values of OpenMaya variables, but my main goal is to get the
allIntersections node working: it should be storing the hitPoints of
the intersections in an MFloatPointArray(), but so far I can only get
the array to store one (0,0,0) point per mesh, which is not what I was
expecting. I'm in world space, I can get the proper faceId and
faceNormal, everything else seems to be working but the array.

...or the array's storing good values, but I'm extracting them
improperly. I can't tell the difference right now.

I've probably just set it up incorrectly, does this sound familiar to
anyone?

Cheers
P

On Feb 21, 9:27 pm, pjrich <zoomcrack...@gmail.com> wrote:
> Just found Jason Osipa's half-startedhttp://docs.osipaentertainment.com/Maya_API_Python_Attribute_and_Type...

damon shelton

unread,
Feb 23, 2010, 1:00:17 AM2/23/10
to python_in...@googlegroups.com
how are you looping through to get and set the intersection points?

are you using MPointArray().append(MPoint(x, y, z))

and when getting the value are you looping through the array and getting each element?

example code:

import maya.OpenMaya as OpenMaya

pointArray = OpenMaya.MPointArray()
for i in range(25):
    pointArray.append(OpenMaya.MPoint(i, i, i))

for i in range(pointArray.length()):
    print pointArray[i].x, pointArray[i].y, pointArray[i].z



pjrich

unread,
Feb 23, 2010, 1:09:59 AM2/23/10
to python_inside_maya
I initialize the variables, then call the allIntersections function,
which takes those variables as arguments, and I'd been assuming it
sets the values of the variables automagically.

Then I'm just using for loops to extract: "for x in hitPoints", etc.

Part of the problem is that I don't know how to look at the array all
at once, to see how the data is formatted inside. When I try to print
the array, I just get a pointer to the array, though I can see there
are MFloatPoints inside. When I try to do a get() as suggested by the
docs I get c++ errors. :P

I'll try the range iterator next though, thanks for that suggestion.

damon shelton

unread,
Feb 23, 2010, 1:22:07 AM2/23/10
to python_in...@googlegroups.com
yea you should be able to loop through the returnedPointArray
the get function helps convert the MPointArray into a C++ friendly array of double arrays which is not in python


pjrich

unread,
Feb 24, 2010, 6:12:45 PM2/24/10
to python_inside_maya
Yep, turns out a "for each" can give very strange results for a
MFloatPointArray... iterating with "for i in range(array.length())"
works properly -- thanks Damon!

Chad Dombrova

unread,
Feb 24, 2010, 6:57:55 PM2/24/10
to python_in...@googlegroups.com

> Yep, turns out a "for each" can give very strange results for a
> MFloatPointArray... iterating with "for i in range(array.length())"

yeah, get used to things not working quite as you expect. check out
my list of gripes here: http://code.google.com/p/pymel/wiki/PythonAPI

viktoras

unread,
Feb 25, 2010, 3:19:54 AM2/25/10
to python_in...@googlegroups.com

> Yep, turns out a "for each" can give very strange results for a
> MFloatPointArray... iterating with "for i in range(array.length())"
> works properly -- thanks Damon!
a little hack i wrote to work around this problem is to use an iterator
function. nothing too smart really, just
simplifies code a bit (no more "list[i]+anotherList[j]" type of code
inside loops). It actually started as a safe way
to iterate over an iterator type (to not forget/skip "next" in iterating
them), but then got extended to support
array types as well.

def mIter(mayaIterator):
'''
shortcut method to iterate maya iterators and lists with foreach
'''

# iterator?
if hasattr(mayaIterator, "isDone"):
while not mayaIterator.isDone():
yield mayaIterator
mayaIterator.next()
# array?
elif hasattr(mayaIterator, "length"):
for i in xrange(mayaIterator.length()):
yield mayaIterator[i]

to use the code, you just write

points = om.MPointArray()
...
for i in mIter(points):
print i.x, i.y, i.z

Reply all
Reply to author
Forward
0 new messages