Thank you. Or I made explicit groups for them, works too. Clearer now.
Next I am trying to do this basic vector subtraction in a Python SOP too. I made a new Python SOP with two inputs. One to take some points and the other to take one point to orient the normals to.
But I am stuck at the very beginning.
geo = hou.pwd().geometry()
Will read in all of the geometry of this node, right? So, how do I distinguish between things incoming from my two inputs?
Thanks again.
Controlling with attractors (modeling challenge)
18281 31 0- anna_waldon
- Member
- 52 posts
- Joined: March 2008
- Offline
- graham
- Member
- 1908 posts
- Joined: Nov. 2006
- Offline
That line of code gets the geometry for the current node, which by default is just the geometry from the first input. You can get the geometry from other inputs by using hou.Node.inputs() and indexing into the input node list it returns. You can then call hou.SopNode.geometry() to get that nodes geometry.
To calculate a unit normal value pointing from each point in the first input geometry to the one point in the second input geometry stored in a standard N attribute I'd do something like this.
geo = hou.pwd().geometry()
input_geo = hou.pwd().inputs().geometry()
target_pos = input_geo.points().position()
normal_attr = geo.addAttrib(hou.attribType.Point, “N”, (0,0,0), True)
for point in geo.points():
normal_value = target_pos - point.pos()
point.setAttribValue(normal_attr, normal_value.normalized())
To calculate a unit normal value pointing from each point in the first input geometry to the one point in the second input geometry stored in a standard N attribute I'd do something like this.
geo = hou.pwd().geometry()
input_geo = hou.pwd().inputs().geometry()
target_pos = input_geo.points().position()
normal_attr = geo.addAttrib(hou.attribType.Point, “N”, (0,0,0), True)
for point in geo.points():
normal_value = target_pos - point.pos()
point.setAttribValue(normal_attr, normal_value.normalized())
Graham Thompson, Technical Artist @ Rockstar Games
- Pagefan
- Member
- 519 posts
- Joined:
- Offline
Anna,
the color_points work because the attractors are sphere primitives, they only have one piont, one primitive and one vertex. So in the color_points I just selected sphere 0, 1 and 2 (hard coded in the group).
I first started out with a single point for attractor (with the same setup) but thought a nice sphere might give some more feedback of what is going on in case you want to animate the attractors.
And yes, Graham is right about the position of the point sops, they should have been before the merge node!
the color_points work because the attractors are sphere primitives, they only have one piont, one primitive and one vertex. So in the color_points I just selected sphere 0, 1 and 2 (hard coded in the group).
I first started out with a single point for attractor (with the same setup) but thought a nice sphere might give some more feedback of what is going on in case you want to animate the attractors.
And yes, Graham is right about the position of the point sops, they should have been before the merge node!
- anna_waldon
- Member
- 52 posts
- Joined: March 2008
- Offline
Thanks once more. On the basis of what you have suggested, here is my effort to calculate the distances to attractors in another Python SOP. It works… I think.
geo = hou.pwd().geometry()
# target_pnt = hou.SopNode(“../PVOL”).geometry()
# this is my feeble attempt to get to the data in another node. How please?
input_geo = hou.pwd().inputs().geometry()
target_red = input_geo.points().position()
target_green = input_geo.points().position()
target_blue = input_geo.points().position()
dist_red_attr = geo.addAttrib(hou.attribType.Point, “dist_red”, (0.0), False, True)
dist_green_attr = geo.addAttrib(hou.attribType.Point, “dist_green”, (0.0), False, True)
dist_blue_attr = geo.addAttrib(hou.attribType.Point, “dist_blue”, (0.0), False, True)
for point in geo.points():
dist_red_value = point.position().distanceTo(target_red)
point.setAttribValue(dist_red_attr, dist_red_value)
dist_green_value = point.position().distanceTo(target_green)
point.setAttribValue(dist_green_attr, dist_green_value)
dist_blue_value = point.position().distanceTo(target_blue)
point.setAttribValue(dist_blue_attr, dist_blue_value)
Please see the question in the code above.
Also, when looking at Pagefan's code, I am not sure I understand correctly:
attribcreate_pointdistance creates one attribute and puts three floats into it referring to distances to each of the attractors, right?
Thank you
geo = hou.pwd().geometry()
# target_pnt = hou.SopNode(“../PVOL”).geometry()
# this is my feeble attempt to get to the data in another node. How please?
input_geo = hou.pwd().inputs().geometry()
target_red = input_geo.points().position()
target_green = input_geo.points().position()
target_blue = input_geo.points().position()
dist_red_attr = geo.addAttrib(hou.attribType.Point, “dist_red”, (0.0), False, True)
dist_green_attr = geo.addAttrib(hou.attribType.Point, “dist_green”, (0.0), False, True)
dist_blue_attr = geo.addAttrib(hou.attribType.Point, “dist_blue”, (0.0), False, True)
for point in geo.points():
dist_red_value = point.position().distanceTo(target_red)
point.setAttribValue(dist_red_attr, dist_red_value)
dist_green_value = point.position().distanceTo(target_green)
point.setAttribValue(dist_green_attr, dist_green_value)
dist_blue_value = point.position().distanceTo(target_blue)
point.setAttribValue(dist_blue_attr, dist_blue_value)
Please see the question in the code above.
Also, when looking at Pagefan's code, I am not sure I understand correctly:
attribcreate_pointdistance creates one attribute and puts three floats into it referring to distances to each of the attractors, right?
Thank you
- anna_waldon
- Member
- 52 posts
- Joined: March 2008
- Offline
- Pagefan
- Member
- 519 posts
- Joined:
- Offline
Also, when looking at Pagefan's code, I am not sure I understand correctly:
attribcreate_pointdistance creates one attribute and puts three floats into it referring to distances to each of the attractors, right?
Yes you are right about that. In the color_volumepoints I use them to make the RGB color. The attribcreate_pointdistance creates the PTDIST attribute. I use that attribute in the color_volumepoints like this: $PTDIST1 for the first value of the 3-float attribute and $PTDIST2 for the 2nd etc…
The truncated line probably means either that it is a secondary input to a node. I guess you deleted your null node and now it is wired into the 2nd input of a copy or point node.
- anna_waldon
- Member
- 52 posts
- Joined: March 2008
- Offline
Thanks.
But the truncated line is something else. It is only short, as in the drawing, and comes out of both inputs and outputs. The node is not visible in the network or in the list, but it is there somewhere because if I create another node with the same name it gets renamed into blah1….
—
EDIT
Hm… I think I did the promotion of the attributes OK but I do not understand how to use PTDIST as in the above post. Create a color attribute color_volumepoints and calculate R G and B? Entering $PTDIST1 there does not work. I also do not understand how to get to (use in an expression) my detail or even where to see it. Middle click shows I have a detail but I cannot see its value in the detail View.
Thank you for the patience.
But the truncated line is something else. It is only short, as in the drawing, and comes out of both inputs and outputs. The node is not visible in the network or in the list, but it is there somewhere because if I create another node with the same name it gets renamed into blah1….
—
EDIT
Hm… I think I did the promotion of the attributes OK but I do not understand how to use PTDIST as in the above post. Create a color attribute color_volumepoints and calculate R G and B? Entering $PTDIST1 there does not work. I also do not understand how to get to (use in an expression) my detail or even where to see it. Middle click shows I have a detail but I cannot see its value in the detail View.
Thank you for the patience.
- graham
- Member
- 1908 posts
- Joined: Nov. 2006
- Offline
target_pnt = hou.SopNode(“../PVOL”).geometry()
You cannot just create an instance of hou.SopNode. The right way to get that geometry would be to do something like this:
target_pt = hou.pwd().node(“../PVOL”)
This specifically says “from this node, look up to my parent and look for the node PVOL”. You could also use the absolute path to attempt to get it as well.
You could also simply go
target_pt = hou.node(“../PVOL”)
because inside the Python SOP Houdini has changed the current working directory to that SOP, but I prefer to always grab things by searching relative to a node, not the current working directory.
You cannot just create an instance of hou.SopNode. The right way to get that geometry would be to do something like this:
target_pt = hou.pwd().node(“../PVOL”)
This specifically says “from this node, look up to my parent and look for the node PVOL”. You could also use the absolute path to attempt to get it as well.
You could also simply go
target_pt = hou.node(“../PVOL”)
because inside the Python SOP Houdini has changed the current working directory to that SOP, but I prefer to always grab things by searching relative to a node, not the current working directory.
Graham Thompson, Technical Artist @ Rockstar Games
- Pagefan
- Member
- 519 posts
- Joined:
- Offline
- anna_waldon
- Member
- 52 posts
- Joined: March 2008
- Offline
- circusmonkey
- Member
- 2624 posts
- Joined: Aug. 2006
- Offline
- anna_waldon
- Member
- 52 posts
- Joined: March 2008
- Offline
Glad it is useful to others…
I just started watching this video on Python in Houdini. Super useful. E.g., getting references to nodes or parameters is automated in the Python shell. Very nice…
http://vimeo.com/14612897 [vimeo.com]
I just started watching this video on Python in Houdini. Super useful. E.g., getting references to nodes or parameters is automated in the Python shell. Very nice…
http://vimeo.com/14612897 [vimeo.com]
-
- Quick Links