Iterating of groups with Python SOP

   12112   16   5
User Avatar
Member
512 posts
Joined: July 2009
Offline
hi,

I created a Python SOP that calculates the dimensions of an object.
Now I want to add a feature which enables the User to input a group prefix
(like piece*) and iterate through every single group object.

Can anybody give me an example on how to approach that ?

thanks,

Manuel
http://vimeo.com/user2522760 [vimeo.com]
http://stormbornvfx.com/ [stormbornvfx.com]
Manuel Tausch
User Avatar
Member
512 posts
Joined: July 2009
Offline
it's actually quite easy to do that.

In my Python SOP I got a parameter field (groupmask) in which
the user can type in a group mask (just like in the foreach SOP).

the code in the Python operator is as following:


sopnode = hou.pwd()
geo = hou.pwd().geometry()
input = sopnode.inputs().geometry().primGroups()
groupmask = sopnode.parm(“groupmask”).evalAsString()

for group in input:
string = group.name()
if string.find(groupmask) == 0:
print group


One thing that I couldn't work out - how would the code look like if I don't want to get an error message if the user inputs a wildcard?
something like “piece_*”

?!?

thanks,

Manu
http://vimeo.com/user2522760 [vimeo.com]
http://stormbornvfx.com/ [stormbornvfx.com]
Manuel Tausch
User Avatar
Member
98 posts
Joined: Sept. 2008
Offline
Hi,

Probably with a regular expression (re)? Have a look at

http//docs.python.org/library/re.html

and use that instead of (string.find(groupmask) == 0) that you're actually using… I guess this could work.

best regards

dagush.-
————————-
* skylineEngine project coordinator
* buildingEngine module developer
http//ggg.udg.edu/skylineEngine
User Avatar
Member
1908 posts
Joined: Nov. 2006
Offline
If you are using a recent build of Houdini 11.1 you can use the new hou.matchesPattern() function to handle it for you.
for group in input:
if hou.matchesPattern(group.name(), groupmask):
print group
Graham Thompson, Technical Artist @ Rockstar Games
User Avatar
Member
512 posts
Joined: July 2009
Offline
thanks guys!
http://vimeo.com/user2522760 [vimeo.com]
http://stormbornvfx.com/ [stormbornvfx.com]
Manuel Tausch
User Avatar
Member
512 posts
Joined: July 2009
Offline
well maybe iterating through groups isn't that easy after all.

disregarding the whole wildcards thing, why is the following code
always outputting me the total number of points of ALL incoming groups instead of just outputting the total of every single one?



sopnode = hou.pwd()
geo = hou.pwd().geometry()
input = sopnode.inputs().geometry().primGroups()
groupmask = sopnode.parm(“groupmask”).evalAsString()

for group in input:
string = group.name()
if string.find(groupmask) == 0:
newgeo = group.geometry()
print len(newgeo.iterPoints())


thanks!
http://vimeo.com/user2522760 [vimeo.com]
http://stormbornvfx.com/ [stormbornvfx.com]
Manuel Tausch
User Avatar
Member
512 posts
Joined: July 2009
Offline
well maybe iterating through groups isn't that easy after all.

disregarding the whole wildcards thing, why is the following code
always outputting me the total number of points of ALL incoming groups instead of just outputting the total of every single one?



sopnode = hou.pwd()
geo = hou.pwd().geometry()
input = sopnode.inputs().geometry().primGroups()
groupmask = sopnode.parm(“groupmask”).evalAsString()

for group in input:
string = group.name()
if string.find(groupmask) == 0:
newgeo = group.geometry()
print len(newgeo.iterPoints())


thanks!
http://vimeo.com/user2522760 [vimeo.com]
http://stormbornvfx.com/ [stormbornvfx.com]
Manuel Tausch
User Avatar
Member
7723 posts
Joined: July 2005
Offline
Because calling group.geometry() returns you the owner geometry object that contains the group, not a geometry object that only contains points from your group.

http://www.sidefx.com/docs/houdini11.1/hom/hou/PointGroup#geometry [sidefx.com]

I think you actually want to call group.points() instead.

http://www.sidefx.com/docs/houdini11.1/hom/hou/PointGroup#points [sidefx.com]
User Avatar
Member
512 posts
Joined: July 2009
Offline
ok, but how do I get the total number of points of each group object then?
http://vimeo.com/user2522760 [vimeo.com]
http://stormbornvfx.com/ [stormbornvfx.com]
Manuel Tausch
User Avatar
Member
7723 posts
Joined: July 2005
Offline
len(group.points())
User Avatar
Member
512 posts
Joined: July 2009
Offline
awesome, thanks Edward!
http://vimeo.com/user2522760 [vimeo.com]
http://stormbornvfx.com/ [stormbornvfx.com]
Manuel Tausch
User Avatar
Member
512 posts
Joined: July 2009
Offline
ok, still struggeling, here's the next problem I ran into:
even if I'm inside a Python SOP operator, I get the following message
as soon as I'm trying to set an attribute value:

GeometryPermissionError: Geometry is read-only.

here's my code. (attempting to create a variable which returns the frame on when the primitives enter their group)


# This code is called when instances of this SOP cook.
sopnode = hou.pwd()
geo = sopnode.geometry()
input = sopnode.inputs().geometry().primGroups()
groupmask = sopnode.parm(“groupmask”).evalAsString()

# Add code to modify the contents of geo.
bool = 0
attrib = geo.addAttrib(hou.attribType.Prim, “onEnterGroup”, 0)

for group in input:
string = group.name()
if string.find(groupmask) == 0:
if bool == 0:
on_enter = hou.frame()
prims = group.prims()
for i in prims:
i.setAttribValue(attrib, on_enter)
bool = 1


thanks!
http://vimeo.com/user2522760 [vimeo.com]
http://stormbornvfx.com/ [stormbornvfx.com]
Manuel Tausch
User Avatar
Member
1908 posts
Joined: Nov. 2006
Offline
All the processing you are doing is on the input geometry, not the geometry of the cooking node, so when you are trying to set your attribute, you are trying to set the value on the primitive in the input geometry, not on the geometry you have access to.
Graham Thompson, Technical Artist @ Rockstar Games
User Avatar
Member
691 posts
Joined: June 2006
Offline
Very nice thread!!!!

Thanks guys.
Feel The Knowledge, Kiss The Goat!!!
http://www.linkedin.com/in/alejandroecheverry [linkedin.com]
http://vimeo.com/lordpazuzu/videos [vimeo.com]
User Avatar
Member
512 posts
Joined: July 2009
Offline
makes sense! I have a look into that, thanks Graham!
http://vimeo.com/user2522760 [vimeo.com]
http://stormbornvfx.com/ [stormbornvfx.com]
Manuel Tausch
User Avatar
Member
16 posts
Joined: Sept. 2012
Offline
graham
If you are using a recent build of Houdini 11.1 you can use the new hou.matchesPattern() function to handle it for you.
for group in input:
if hou.matchesPattern(group.name(), groupmask):
print group

I found the above python pattern matching function is incorrect. hou.matchesPattern(group.name(), groupmask)
The correct function is as follows:-
hou.patternMatch(groupmask, group.name())
http://www.sidefx.com/docs/houdini15.0/hom/hou/patternMatch [sidefx.com]
User Avatar
Member
1799 posts
Joined: Oct. 2010
Offline
Did not know about this method here.. brilliant!
-G
  • Quick Links