[Solved] Unable to properly link float ramps via script

   2903   8   0
User Avatar
Member
4 posts
Joined: June 2018
Offline
Hello,

I hope somebody can help me out as I have run into a problem when linking ramps via script that I have been unable to solve for more than a week now. What I would like to achieve is exactly the same effect that using “Copy Parameter” / “Paste Relative References” does when doing this from the user interface. I tried both python and hscript. The problem is that once the ramps are linked, when I add new control points to the parent, the child gets the control points but doesn't get the positions (ramp#pos) and values (ramp#value). In python I simply tried to set one float ramp parm to the other like this:

hou.parm("/obj/node_B/ramp_B").set(hou.parm("/obj/node_A/ramp_A"))

This seemed like the most simple and straightforward way of doing this but it failed so I reported it to the SideFX guys and they confirmed that python is not feature-complete for linking ramps with the .set() command - first they logged it as Bug #97192 then it was reconsidered to be an RFE with the same ID. After this SideFX suggested to use hscript opmultiparm which I proceeded to do but the ramp linking failed this time too. I am fairly confident using python but not so much with hscript so I am hoping it's my inability to use hscript properly this time rather than another bug - this is what I did:

opmultiparm /obj/node_B/ 'ramp_B#pos' '/obj/node_A/ramp_A#pos' 'ramp_B#value' '/obj/node_A/ramp_A#value' 'ramp_B#interp' '/obj/node_A/ramp_A#interp'

What I noticed in the “Edit Parameters” interface is if I manually type in the path to link the ramps then it does work the same as “Copy Parameter” / “Paste Relative References” - see below. I wonder if this field is exposed to python or hscript somewhere and maybe I should try to set this?



Other than the above I also used both opscript and .asCode() after setting up the ramps links manually to see if it gives me the proper code and even if I run the code I get back from these the ramp linking still fails.

Has anybody ever found a reliable solution for linking ramps in script? Anybody got any ideas where to go from here?
Edited by vime_mohn - June 18, 2019 11:44:44

Attachments:
image.png.4531fb3916a0ee461d7401502db49509.png (44.6 KB)

User Avatar
Member
4 posts
Joined: June 2018
Offline
I found a solution in this post from user jsmack
https://www.sidefx.com/forum/topic/59899 [www.sidefx.com]
User Avatar
Member
900 posts
Joined: Feb. 2016
Offline
I'm pretty sure that the trick is to EVALUATE the ramp parameter when you set it as reference.

try this

hou.parm("/obj/node_B/ramp_B").set(hou.parm("/obj/node_A/ramp_A").eval())


from the docs [www.sidefx.com]:
“If you evaluate a ramp parameter on a node, Houdini will return a Ramp object.”
Edited by Andr - June 18, 2019 11:54:58
User Avatar
Member
7 posts
Joined: Jan. 2019
Offline
Hi @Andr

I'm a colleague of OP. We have tried your suggestion - what it does is it sets the values of the ramp once but no link is created between the two. For the moment the following solution seems to be the only reliable one:

from pyro2 import xferLinkParm
xferLinkParm(
    hou.parm("/obj/node_A/ramp_A"),
    hou.parm("/obj/node_B/ramp_B")
)
User Avatar
Member
900 posts
Joined: Feb. 2016
Offline
This seems strange,
check the example file, it's working for me

cheers

Attachments:
linkrampspython.hiplc (45.7 KB)

User Avatar
Member
7 posts
Joined: Jan. 2019
Offline
Hi Andr, thanks for the file. In your example this seems to work because your controller and dummy are part of the same node chain. When you change source it forces the downstream nodes to cook so the python code runs over and over again, updating the dummy ramp every time you change the controller ramp. In my case, the ramps are on two disconnected nodes (sometimes in completely different networks) without using python nodes.

If you try the traditional methods like dst_ramp.set(src_ramp) or dst_ramp.set(src_ramp.eval()) in a python shell in the file I attached, you can see that the link is somewhat there but not working as intended. The xferLinkParm thing from pyro2 will work though. I do not understand completely, how it is achieved in the xferLinkParm function to be honest but I am glad it exists.

It would be very strange if setting the ramps the traditional way was working for you with my file as even SideFX has confirmed this as a bug/request for enhancement.

Attachments:
Ramps.hip (45.6 KB)

User Avatar
Member
900 posts
Joined: Feb. 2016
Offline
Hello,

just for the sake of completeness, you could also set a callback script on the “Ramp_from” parameter that would update the “Ramp_to” every time the callback is triggered (every time you modify the ramp).

This is the inline code I used for the callback:
dummy=hou.pwd().node("/obj/to").parm("ramp_to"); thisRamp=hou.pwd().parm("ramp_from").eval(); dummy.set(thisRamp)
Anyway, glad that u already found another solution.

cheers
Edited by Andr - June 21, 2019 09:53:36

Attachments:
callback_Ramps.hiplc (43.4 KB)

User Avatar
Member
7 posts
Joined: Jan. 2019
Offline
Hello Andr, that's a pretty neat trick. I had no idea that you could use the callback script on a ramp in this fashion. I have only started scripting in Houdini a few weeks ago so there is a lot to learn. Thanks for your input and have a great weekend!
User Avatar
Member
21 posts
Joined: Dec. 2008
Offline
adding this for anyone interested in doing everything in python
This sets the callback script and language, then triggers the callback:
and the destination ramp's path is relative

source_ramp = hou.parm('/obj/ground_explosion/ramps/ramp_a')
dest_ramp = hou.parm('/obj/ground_explosion/ramps/ramp_b')

def copyRefRamp(source_ramp,dest_ramp):
    ptg = source_ramp.node().parmTemplateGroup()
    source_ramp_template = ptg.find(source_ramp.name())    
    dest_ramp_relpath = source_ramp.node().relativePathTo(dest_ramp.node())+"/"+dest_ramp.name()   
    callbackScript = 'dest_ramp=hou.parm("'+dest_ramp_relpath+'");source_ramp=hou.pwd().evalParm("'+source_ramp.name()+'"); dest_ramp.set(source_ramp)'
    tags = {}
    tags["script_callback_language"]="python"   
    tags['script_callback']=callbackScript
    source_ramp_template.setTags(tags)
    ptg.replace(source_ramp.name(),source_ramp_template)
    source_ramp.node().setParmTemplateGroup(ptg)

copyRefRamp(source_ramp,dest_ramp)

# trigger callback
source_ramp.pressButton()
Edited by bunker__ - March 29, 2021 22:32:32
  • Quick Links