Jump to content

VEX Wrangle error: Read-only expression given for read/write parameter


jkunz07

Recommended Posts

I have a function I'm trying to define in a wrangle.  If I use the code below in an attribute/point wrangle everything works OK.

vector slerpv(vector a_vec; vector b_vec; float bias)
{   
    float a_mag = length(a_vec);
    a_vec = normalize(a_vec);
    float b_mag = length(b_vec);
    b_vec = normalize(b_vec);
    vector4 a_quat = quaternion(a_vec);
    vector4 b_quat = quaternion(b_vec);
    vector out_vec = qconvert(slerp(a_quat, b_quat, bias));
    out_vec = normalize(out_vec);
    return out_vec *= lerp(a_mag, b_mag, bias);
}

vector a = set(1,0,0);
vector b = set(0,1,0);
v@N = slerpv(a, b, fit(sin(@Time),-1,1,0,1));

If I try change the last line of the above code to multiply one of the first two arguments like so:

v@N = slerpv(a, b*5.0, fit(sin(@Time),-1,1,0,1));

I get the following errors and the node will error out.

Error:       The sub-network output operator failed to cook: /obj/geo1/attribwrangle7/attribvop1
Error:       Error in VOP 'snippet1'.
Warning:     Errors or warnings encountered during VEX compile:
             /obj/geo1/attribwrangle7/attribvop1/snippet1: Read-only expression given for read/write parameter.  (16,27).
Error:       Error in VOP 'snippet1'.
Warning:     Errors or warnings encountered during VEX compile:
             /obj/geo1/attribwrangle7/attribvop1/snippet1: Read-only expression given for read/write parameter.  (16,27).
Error:       Vex error: /obj/geo1/attribwrangle7/attribvop1/snippet1: Read-only expression given for read/write parameter.       (16,27)
Failed to resolve VEX code op:/obj/geo1/attribwrangle7/attribvop1Unable to load shader 'op:/obj/geo1/attribwrangle7/attribvop1'.
Warning:     Message node has warning.
____________________________________________________________________________________________________________________________________
Messages from attribvop1:
Error:       Error in VOP 'snippet1'.
Warning:     Errors or warnings encountered during VEX compile:
             /obj/geo1/attribwrangle7/attribvop1/snippet1: Read-only expression given for read/write parameter.  (16,27).
Error:       Error in VOP 'snippet1'.
Warning:     Errors or warnings encountered during VEX compile:
             /obj/geo1/attribwrangle7/attribvop1/snippet1: Read-only expression given for read/write parameter.  (16,27).
Error:       Vex error: /obj/geo1/attribwrangle7/attribvop1/snippet1: Read-only expression given for read/write parameter.       (16,27)
Failed to resolve VEX code op:/obj/geo1/attribwrangle7/attribvop1Unable to load shader 'op:/obj/geo1/attribwrangle7/attribvop1'

Does anyone know how I can fix this?

Link to comment
Share on other sites

The documentation says: “As in RenderMan Shading Language, parameters to user functions are always passed by reference, so modifications in a user function affect the variable the function was called with”. Or, as the error log says, your function parameter is set as read/write.

 

When you do `b * 5.0` in your code, what's happening is that a new temporary object is being created, which is similar to C/C++'s r-values, and it is not possible to pass such objects to reference parameters because they are not held by any variable.

 

This doesn't apply to simple built-in types such as `int` and `float` which are passed by copy rather than reference for optimization purposes, so this is why the call to `fit()` doesn't trigger the error. Also, the functions built-in in VEX seem to be able to define read-only parameters, which would make your parameter valid if it was passed to the `slerp()` function in example.

 

To fix this, you simply need to store your operation into a new variable such as `vector c = b * 5.0;` before passing it to your function. This shouldn't cause any performance penalty since the same amount of memory would have been allocated with your temporary object anyways. The only difference is that the variable `c` will be held in memory for longer instead of being deallocated just after being used. No big deal.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Well, I have overlooked the 2nd part of the sentence that I've quoted from the documentation :)

 

“You can force a shader parameter to be read-only by prefixing it with the const keyword.”

 

So, much better for you would be to add the `const` keyword in front of your function parameters.

 

Also, by rereading your code, I see that you are actually modifying (normalizing) the arguments `a_vec` and `b_vec`, which is probably not what you want, ie:

 

void myFunction(vector v1)
{   
    v1 = normalize(v1);
}


vector a = set(99, 0, 0);
myFunction(a);

// a is now equal to [1, 0, 0]!!
 
Link to comment
Share on other sites

so if parms are passed as reference, you can't pass the result of a function call (read only).

 

have a temp variable hold the result of your fit() call and then pass that to your function.

 

see if that fixes things.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...