How to get JSON formatted strings from Ramps

   3688   12   2
User Avatar
Member
77 posts
Joined: Feb. 2017
Offline
Hi all:

I tried the H18.5's new VEX function - ramp_unpack / ramp_lookup yesterday.

But I'm confused with the introduction of the ramp_unpack function.
Ramps are commonly packed as JSON formatted strings by Houdini operations.

To my understanding, the ramp_unpack's string parm need a JSON formatted strings from ramp channel.
But how can I get the right json string?

I tried the “Attribute from Parameters” SOP, but the dict(will be converted to JSON use json_dumps function) it gets from ramp channel seems is not the right format which ramp_unpack needs.
I post my hip here.

Does anyone can help me? Thanks.
Edited by zengchen - Nov. 1, 2020 05:51:07

Attachments:
zzzz.png (25.0 KB)
test.hip (86.1 KB)

My Youtube Channel [www.youtube.com]
User Avatar
Member
77 posts
Joined: Feb. 2017
Offline
Ok, I finally find the “Flatten Ramps” option on “Attribute from Parameters” SOP

it works correctly this time…

I find it can use dict attribute to store ramp / multiparms now in Houdini 18.5, it is really nice.

PS: the “Attribute from Parameters” SOP always grabs the parameter values at the current time. So it seems impossible to get right multiparms if the parms are changing with time.
Edited by zengchen - Nov. 1, 2020 11:28:59

Attachments:
2020-11-01_201116.png (16.6 KB)
test_fixed.hip (84.1 KB)

My Youtube Channel [www.youtube.com]
User Avatar
Member
192 posts
Joined: April 2015
Offline
Thanks,

I would wanna know if it’s possible to pack it back again, to the string argument,

Or should we have to have it as those 3 arrays if we want to carry it along the node tree as a changeable attribute?
User Avatar
Member
192 posts
Joined: April 2015
Offline
I would need to know that now,

Because the ramp_lookup function doesn't get me the same result when given the three arrays:


I'll log this as a bug to SideFX,
If someone knows a way to fix this, or how to pack the ramp back again, I'd like to know. :-)

hip file attached:
Edited by OdFotan - June 6, 2021 15:29:29

Attachments:
giphy.gif (558.8 KB)
ramp_lookup() bug.hiplc (130.4 KB)
Screenshot 2021-06-06 at 21.10.13.png (12.5 KB)

User Avatar
Staff
6169 posts
Joined: July 2005
Offline
The ramp_lookup() for arrays is a wrapper around what used to be ramp_lookup in pyro_aaramp. That did a linear warp of the sample position into a uniform key distribution, and then sampled the ramp as if the keys were uniform. I'm guessing maybe the full key spline function wasn't present when that was written, and it "gets away" with it for many ramp types as the key spacing isn't important. But for bsplines it is pretty important!

Fortunately there is a workaround, rather than ramp_lookup() you can go directly to the spline function:

    y = spline(s[]@r_basis, x, f[]@r_val, f[]@r_key);

Hopefully we can fix ramp_lookup, but you probably want to use the spline() version for backwards compatibility in 18.5 for a while.
User Avatar
Member
192 posts
Joined: April 2015
Offline
Interesting. I didn't expect the spline function to work it because the docs didn't mention 'bspline' as an possible option for the basis argument.

Thank you.
User Avatar
Staff
6169 posts
Joined: July 2005
Offline
Ah, good point, the spline docs have not been updated. It uses the same underlying code as the Ramp, so thus in practice they will remain in sync.

18.5.605 will have ramp_lookup() working as expected, and adds ramp_pack to do the to-string operation if you need it.
User Avatar
Member
385 posts
Joined: July 2018
Offline
How can i write a ramp to a json file? i ma trying to construct a dictionary but i am stuck here
import json

node = kwargs['node']
ramp = node.parm('ramp').multiParmInstances()
num = node.parm('ramp').multiParmInstancesPerItem()

dict = {
    'point': []
}
for p in ramp:
    data = {}
    for i in range(num): 
        if str(i+1) in p.name():
            value = p.eval()
            name = p.name()
            data[name] = value 
    dict['point'].append[data]
 
print(dict)       
Edited by papsphilip - Oct. 13, 2021 12:28:36
User Avatar
Member
8520 posts
Joined: July 2007
Online
papsphilip
How can i write a ramp to a json file? i ma trying to construct a dictionary but i am stuck here
there is an error in this line:
dict['point'].append[data]
should look like this
dict['point'].append(data)

beyond that I'm not sure if you are trying to match specific json structure of ramp parameter, like the one that Attribute From Parameters is using or keeping it as custom, but this should at least fix the error
Edited by tamte - Oct. 13, 2021 12:46:58
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
385 posts
Joined: July 2018
Offline
tamte
beyond that I'm not sure if you are trying to match specific json structure of ramp parameter
i am trying to end up with a json file that looks like this:

ramp name

-point1
--pos
--val
--interp

-point2
--pos
--val
--interp

-point3
--pos
--val
--interp

the error got fixed indeed but the dictionary is messed up
Edited by papsphilip - Oct. 13, 2021 12:53:04
User Avatar
Member
385 posts
Joined: July 2018
Offline
ok i had to turn my loops inside out


import json

node = kwargs['node']
ramp = node.parm('ramp').multiParmInstances()
num = node.parm('ramp').multiParmInstancesPerItem()

dict = {
    'point': []
}

for i in range(num): 
    data={}
    for p in ramp:
        if str(i+1) in p.name():
            value = p.eval()
            name = p.name()
        
            data[name] = value 
            
    dict['point'].append(data)   
    
print(dict)
User Avatar
Member
8520 posts
Joined: July 2007
Online
papsphilip
i am trying to end up with a json file that looks like this:
...
instead of doing each point as a separate dict value I'd suggest doing a list
here is how it would look like for example:
parm = node.parm('ramp')
ramp = parm.evalAsRamp()
interplookup = [hou.rampBasis.Constant, hou.rampBasis.Linear, hou.rampBasis.CatmullRom, hou.rampBasis.MonotoneCubic, hou.rampBasis.Bezier, hou.rampBasis.BSpline, hou.rampBasis.Hermite]

keylist = []
for i, key in enumerate(ramp.keys()):
    data = { "pos": key,
             "value": ramp.values()[i],
             "interp": interplookup.index(ramp.basis()[i])}    
    keylist.append(data)

dict = { parm.name(): keylist }
print(dict)   

but obviously its up to you
Edited by tamte - Oct. 13, 2021 13:28:18
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
385 posts
Joined: July 2018
Offline
tamte
ramp = parm.evalAsRamp()

This is very helpful thank you! also i didn't know about the evalAsRamp().
How can you set the ramp parameters from the dict you just made?
  • Quick Links