Jump to content

mimic for each 'attribute value' in python


sly

Recommended Posts

Hi,

i would like to know if there is a way to loop through points via an attribute value , like the ForEach node does when it s setup on 'each attribute value' . i already know how to make simple loops , but i m stucked in the way to do that via an attrbute value stored in the points.

if someone has some ideas , please share :)

thanks.

Sylvain.

Edited by sly
Link to comment
Share on other sites

## I'm kinda new to this as well.

## Is there a better way?

import hou

h=hou.node("/obj/torus_object1/torus1")

g=h.geometry()

p=g.points() # get list of points geo

# pre-get attributes if you wanna find out what's available?

#

a_pt = p[0]

pt_geo = a_pt.geometry()

l_attrs = pt_geo.pointAttribs()

print "attribues:",l_attrs

#### now go through points for whatever attrib value..

## point position in this simple case.

print "size p:",len(p)

for pt in p:

print i

i +=1

# For now, just print attribute "P"

print pt.attribValue("P")

Edited by moomarkus
Link to comment
Share on other sites

so i create a dictionary this way :

pts = geo.points()

dico = {}

for pt in pts:

ptNum = pt.number()

attrValue = pt.attribValue("class")

dico[ptNum] = attrValue

is this the correct way ?, i m very noob in python.

now i have to find how to use this.

Edited by sly
Link to comment
Share on other sites

I threw this together real quick in an attempt to make something that would try and handle things as efficiently as possible. As it requires numpy and collections so it might not work on all platforms unless those modules are available. It also doesn't support string attributes.

This function returns a defaultdict object whose keys are unique attribute values and whose indices are any entity number(s) whose values correspond to the key. It supports points or primitives of any size.

from collections import defaultdict
import numpy

def getPartitionedIndices(attribute):
    attribType = attribute.type()
    dataType = attribute.dataType()
    name = attribute.name()
    size = attribute.size()

    # Can't handle string attributes.
    if dataType == hou.attribData.String:
        raise hou.OperationFailed("Attribute cannot be a string attribute.")


    if attribType == hou.attribType.Point:
        values = numpy.fromstring(attribute.geometry().pointFloatAttribValuesAsString(name), dtype=numpy.float32)

    elif attribType == hou.attribType.Primitive:
        values = numpy.fromstring(attribute.geometry().primFloatAttribValuesAsString(name), dtype=numpy.float32)

    else:
        raise hou.OperationFailed("Invalid attribute type for {0}.  Must be point or primitive.".format(name))

    # Convert to integers if necessary.
    if dataType == hou.attribData.Int:
        values = values.astype(numpy.int)

    ddl = defaultdict(list)

    # Handle attributes whose size is > 1.
    if size > 1:
        # If the size is not 1 we need to reshape the flat array to group components together.
        values = numpy.reshape(values, (float(len(values)) / size, size))

        for idx, val in enumerate(values):
            # Need to convert away the numpy-ness and create at tuple which is hashable.
            ddl[tuple(val.tolist())].append(idx)
    else:
        for idx, val in enumerate(values):
            ddl[val].append(idx)

    return ddl

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...