Any progress in SubD methods?

Hi @maje90,

Thanks for coming back to this thread and showing us what doesn’t work for you. As you noticed, some of the iterators (faces) already work with foreach, while others do not (vertices).

This kind of issues is exactly what I meant above when I wrote that I was working on improving these, the plan is to have all of them work with foreach (and its parallel version for const operations), as well as the iterators for the neighborhoods of vertices, edges and faces. So this is being worked on and will be easier to use soon.

However, I’m still confused about what you’ve been writing about .First, .Next etc. Why does that feel like “giving up” to you? What are you trying to do that fundamentally does not work with that?

The reason I’m asking is that support for foreach will not bring new capabilities to these iterators, it is just syntaxic sugar that saves you a little bit of typing. (Support for Parallel.ForEach is a little bit more involved but let’s keep that out of the discussion for now.) So if First and Next are missing capabilities for you to get your work done, I need to know about it now to fix it now.

Here’s a Python 3 example based on your last attempt:

v = subd.Vertices.First
while v != None:
    if v.FaceCount > 4:
        print(f"{v.Id} ({v.ControlNetPoint}): {v.FaceCount}")
    v = v.Next

Is that what you are looking for?

When SubD.Vertices supports foreach, the above Python code would look like this:

for v in subd.Vertices
    if v.FaceCount > 4:
        print(f"{v.Id} ({v.ControlNetPoint}): {v.FaceCount}")

Easier to read and write for sure, but not fundamentally more capable than the previous version.

FYI, you can reproduce that behavior now with a custom iterable class in Python, and probably in C# as well:

class SubDVertexIterator:
    __slots__ = 'iterator', 'current'

    def __init__(self, subd: Rhino.Geometry.SubD):
        self.iterator = subd.Vertices
        self.current = None

    def __iter__(self):
        self.current = self.iterator.First
        return self
    def __next__(self):
        if (current := self.current) is None:
            raise StopIteration
        self.current = current.Next
        return current

for v in SubDVertexIterator(subd):
    if v.FaceCount > 4:
        print(f"{v.Id} ({v.ControlNetPoint}): {v.FaceCount}")
    v = v.Next (959 Bytes)
DI-165226_PEC_SubD-Iter.3dm (298.6 KB)