[HOM]: get the list of Float Point Attributes

   10955   11   1
User Avatar
Member
77 posts
Joined: April 2009
Offline
Hi!

Probably silly question…

I can get the float attribute value by parsing points of my geometry:

geo=hou.pwd().geometry()
pointAttrArray = geo.pointAttribs()
for attr in pointAttrArray:
if attr.name() == “P”: # <– or another point float attribute
for point in geo.points():
print point.floatListAttribValue(attr.name())

The question is:

Is it possible to get complete list of float values stright from geo?

Something like geo.floatListAttribValue(“P”)

Thank you in advance!
User Avatar
Member
1908 posts
Joined: Nov. 2006
Offline
hou.Geometry.pointFloatAttribValues(“P”) will give you a giant tuple of all the point positions values.
Graham Thompson, Technical Artist @ Rockstar Games
User Avatar
Member
77 posts
Joined: April 2009
Offline
Ah!

Thank you, graham!
User Avatar
Member
77 posts
Joined: April 2009
Offline
One more similar question:

Can I get string attribute on points by the similar way (in one pass?)

Thank you!
User Avatar
Member
1908 posts
Joined: Nov. 2006
Offline
Unfortunately there currently is no similar method for String attributes. There exists an RFE for one that may be implemented in the future.
Graham Thompson, Technical Artist @ Rockstar Games
User Avatar
Member
77 posts
Joined: April 2009
Offline
One more question, about vertices.

As I can understand, I have to iterate through all primitives and all they vertices to collect, for example, uv and N attributes?

That would be great to get the vtx list from hou.Geometry, similar as for the points… That could save a lot of performance on huge meshes…

REALLY hope to future implementation.

Cheers!
User Avatar
Member
1908 posts
Joined: Nov. 2006
Offline
Getting a list of vertex attribute values is a much harder task than getting a list of point/prim attributes like you can now. The advantage now is how Houdini stores points and primitives, in a list for each. However, vertices stored through primitives, so internally Houdini would have to do the exact same thing you are doing and would not be as fast as the point method.

Also, there is a further problem where depending on what it is you are doing there is really no easy way to figure out what anything in the list is. When dealing with points/prims you easily know that say the value at index 30 in a list of attribute values for an attribute of size 1, that element corresponds to point 31. However, since vertices are based on primitives, prim 0 might have 3 verts, prim 1 might have 7, etc… I've played with the idea and wrote my own slow method but then I really don't get any advantage of doing it this way. You can sort of iterate over all the prims, then play around with indexing that way but it's still slower.

In summary though, if there ever can be a method similar to this I would not expect it until at least the next version of Houdini when the geometry library has been refreshed and may offer a better way to do this.
Graham Thompson, Technical Artist @ Rockstar Games
User Avatar
Member
1908 posts
Joined: Nov. 2006
Offline
Another thing I meant to mention earlier, when you are iterating over elements and getting their attribute value, you should probably pass the actual hou.Attrib object to the attribute value returning function as opposed to attribute.name(). It can be much quicker for Houdini to use the actual attribute pointer to look up the value than by passing the name. When you compound this by a large number of points/prims you can get some noticeable speed increases.
for attr in geo.pointAttribs()
if atter.name() == “P”:
for point in geo.points():
print point.attribValue(attr)

Also, if all you want is a particular attribute then I'd just say search for it.
p_attr = geo.findPointAttrib(“P”)
if p_attr is not None:
for point in geo.points():
print point.attribValue(p_attr)
Graham Thompson, Technical Artist @ Rockstar Games
User Avatar
Member
77 posts
Joined: April 2009
Offline
Thank you, graham, for spending your time for answers!

Actually, I am getting all attributes (prim, point and vertex) in one loop through geometry vertices.

Like that:

for prim in geo.prims():

for attr in primAttrArray:
<to do something with primitive attributes>

vtxList = geo.iterPrims().vertices()

for vertex in vtxList:
point = vertex.point()

Here I need to check: “Do we've passed this point already?” (to avoid redundant information)
If not - then get this point attributes.


if not points_db.has_key(point.number()):
points_db = point

# — getting the point attributes —
for attr in pointAttrArray:
if attr.dataType() == hou.attribData.Float:
pointvalue = point.floatListAttribValue(attr)

elif attr.dataType() == hou.attribData.Int:
pointvalue = point.intListAttribValue(attr)

elif attr.dataType() == hou.attribData.String:
if attr.size() > 1:
pointvalue = point.stringListAttribValue(attr)
else:
pointvalue = point.stringAttribValue(attr.name())

pointAttribs_db = str(pointvalue)

# — getting the vertex attributes —
for attr in vtxAttrArray:
<To do something with vertices>

After all, I would report not critical, but very noty bag for string attribute.

I have to check the size of point string attribute. And to use point.stringAttribValue() - for single size or point.stringListAttribValue() - for bigger.

Help telling me:

It is valid to call this method when the attribute’s size is 1. In this case, a tuple with one element is returned.

But in real I will get (for string attribute):
('', ‘string text’)

but not right value:
'string text'

… just for your case.
User Avatar
Member
77 posts
Joined: April 2009
Offline
One more things about single attribute length:

for integer we'll get:
but the right array will be:

For float attributes we'll get:
but the right will be:

So, better scropt will be:

for attr in pointAttrArray:
if attr.dataType() == hou.attribData.Float:
if attr.size() > 1:
pointvalue = point.floatListAttribValue(attr)
else:
pointvalue = point.floatAttribValue(attr)

elif attr.dataType() == hou.attribData.Int:
if attr.size() > 1:
pointvalue = point.intListAttribValue(attr)
else:
pointvalue = point.intAttribValue(attr)

elif attr.dataType() == hou.attribData.String:
if attr.size() > 1:
pointvalue = point.stringListAttribValue(attr)
else:
pointvalue = point.stringAttribValue(attr.name())

But once again, this is not critical bug (till we'll start parsing result)
User Avatar
Member
1908 posts
Joined: Nov. 2006
Offline
I think you are just terribly over complicating your code. You don't need the majority of that code at all. Is there some reason you can't simply call hou.Point.attribValue()? Looking at your code I see no reason whatsoever why you'd want to constantly check types and use different attribute fetching functions.

If you read the help for any of those functions they talk about how you would most likely use attribValue() and that all those get value functions are just used internally.
Graham Thompson, Technical Artist @ Rockstar Games
User Avatar
Member
77 posts
Joined: April 2009
Offline
The target for my code is to get strings for each attributes, primitive, points and vertices.

The reason to parse the types and sizes of attributes - wrong values in “universal” methods.

As I wrote before:

- not equal of , isn't?

When you'll parse this strings later, in another CG pakage, you'll get tuples for first example and integers for second.

I hope you understand what I mean…

Thank you for your time anyway!
  • Quick Links