0

While trying some basic programming in Maya I came across the "MitMeshPolygon" method. Which was described as: "This class is the iterator for polygonal surfaces (meshes)."

(https://help.autodesk.com/view/MAYAUL/2016/ENU/?guid=__py_ref_class_open_maya_1_1_m_it_mesh_polygon_html)

This seemed to be what I needed, so I looked into iterators more and from what I can tell, iterators should themselves be iterable, and have a iter method. However, when trying to iterate over it python told me it wasn't iterable.

        iterable = OpenMaya.MItMeshPolygon(dagPaths[0])            
        while not iterable.isDone():
            print(iterable)
            print(dir(iterable))

<maya.OpenMaya.MItMeshPolygon; proxy of <Swig Object of type 'MItMeshPolygon *' at 0x0000021A9159D630> >

['class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'gt', 'hash', 'init', 'init_subclass', 'le', 'lt', 'module', 'ne', 'new', 'next', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'swig_destroy', 'weakref', 'center', 'className', 'count', 'currentItem', 'geomChanged', 'getArea', 'getAxisAtUV', 'getColor', 'getColorIndex', 'getColorIndices', 'getColors', 'getConnectedEdges', 'getConnectedFaces', 'getConnectedVertices', 'getEdges', 'getNormal', 'getNormals', 'getPointAtUV', 'getPoints', 'getTriangle', 'getTriangles', 'getUV', 'getUVArea', 'getUVAtPoint', 'getUVIndex', 'getUVSetNames', 'getUVs', 'getVertices', 'hasColor', 'hasUVs', 'hasValidTriangulation', 'index', 'isConnectedToEdge', 'isConnectedToFace', 'isConnectedToVertex', 'isConvex', 'isDone', 'isHoled', 'isLamina', 'isPlanar', 'isStarlike', 'isUVReversed', 'next', 'normalIndex', 'numColors', 'numConnectedEdges', 'numConnectedFaces', 'numTriangles', 'onBoundary', 'point', 'polygon', 'polygonVertexCount', 'reset', 'setIndex', 'setPoint', 'setPoints', 'setUV', 'setUVs', 'tangentIndex', 'this', 'thisown', 'updateSurface', 'vertexIndex', 'zeroArea', 'zeroUVArea']

I want to iterate through all the polygons and "getArea", but right now I have no idea how to do it, everything I read tells me iterators should be iterable, but the program tells me otherwise. What am I not understanding here? How do I use these methods to get specific information concerning the object indicated by the DagPath?

  • Does `for item in iterable:` not work? – 9769953 Apr 09 '21 at 11:05
  • Note that there is a `__next__` method, so you should be able to called `next(iterable)` inside a `while True:` loop, and it will raise `StopIteration` once done. – 9769953 Apr 09 '21 at 11:11
  • 1
    Unduping. This object is not an iterator in the standard sense of the word in Python. You'll have to interact with it in some sort of Maya-specific way. Looking through the method list, `count`, `next`, and `currentItem` look like they might be the way to go, but I don't know enough about Maya to be confident in how this thing should be used. – user2357112 Apr 09 '21 at 11:14
  • @user2357112supportsMonica Why then is there `__next__` listed in the output of `dir()`? – 9769953 Apr 09 '21 at 11:16
  • @00: Odd... that's not in the online docs, and it's missing `__iter__`, which all iterators are supposed to have. I guess this thing might be half-usable as an iterator. – user2357112 Apr 09 '21 at 11:18
  • The documentation shows the `next()` method, which I guess is copied from the C++ API. Possibly, that does exactly the same as calling `__next__`, and then either using the `next()` method on `iterable` or `next(iterable)` both work. – 9769953 Apr 09 '21 at 11:23
  • for item in iterable: tells me the object isn't iterable. I noticed the page I linked was from an older version of maya, and the 2022 version does have both __init__ and __next__ listed as methods. 2022 is the version I have though, and those are not listen when I dir() them in the program. – Stijn Klessens Apr 09 '21 at 11:28
  • `__ next__` is right there in your output. `__init__` is the only one missing. – 9769953 Apr 09 '21 at 11:34
  • 2022? If that relates to the year, they are a bit ahead of things. – 9769953 Apr 09 '21 at 11:35
  • Sorry, I meant __init__ is missing yeah, and yeah, they're cutting edge XD – Stijn Klessens Apr 09 '21 at 11:44
  • Iterators are a Computer Programming Design Pattern. In the documentation they state those classes as iterators in the broader sense of the term, not as the Python implementation. [link](https://en.wikipedia.org/wiki/Iterator_pattern) – Klaudikus Jun 06 '21 at 15:16

1 Answers1

0

Your iterable has a __next__ method. You may be able to do something like the following:

iterator = OpenMaya.MItMeshPolygon(dagPaths[0])            
try:
    while True:
        item = next(iterator)
        ...
except StopIteration:
    pass

Note that I have renamed the variable to iterator, since that appears to be the slightly more correct term. An iterable should indeed have an __iter__ method, and calling iter(iterable) turns it into an iterator that does the actual iteration, and has a __next__ method.

In fact, iterator may actually be a generator, yielding values on the go (using next()), and you wouldn't be able to access randomly located values (with, for example, indexing), only one after the other. Then you only need a __next()__ method. But without seeing the actual code for MitMeshPolygon, that is a guess.

9769953
  • 10,344
  • 3
  • 26
  • 37