Jump to content

What is the reasoning behind the variable behavior?


kgoossens

Recommended Posts

Hi,

For a long time I've been using the variables in the transform sop in combination a second transform node to undo the translation.

For example:

using -$CEX in the first transform to center an object's position.

Then using -ch("../xform1/tx") to undo that position.

This doesn't work anymore since H12.1. And I filed it as a bug but apparently this is how it should work.

And it is easy to solve using a bbox expression.

But I do not understand the reasoning why a variable wouldn't return a value.

Link to comment
Share on other sites

I don't know what has changed in H12.1, but I usually use a single TransformSOP with -$CEX in tx (and $CEX optionally in pivot), and it does work cancelling transformation (puts mesh into origin). Is that what you intend to do?

The problem is when you channel reference that later on in the network to reverse the translation it doesn't work.

It used to work but doesn't anymore! I had this problem the other day, took ages to track down the problem...

Edited by sam.h
Link to comment
Share on other sites

can not reproduce it, mabe You are referencing from bottom to top?

The problem is when you channel reference that later on in the network to reverse the translation it doesn't work.

It used to work but doesn't anymore! I had this problem the other day, took ages to track down the problem...

Link to comment
Share on other sites

can not reproduce it, mabe You are referencing from bottom to top?

I've added an example.

Also when toggling the parameter view to see the values, you will not see the values used to change the position in the xform using the variables.

VariableExample.hipnc

Edited by kgoossens
Link to comment
Share on other sites

in 12.1.33 it still works the newer build seems to fail. maybe something broke when they added the move centroid to origin button.

I've added an example.

Also when toggling the parameter view to see the values, you will not see the values used to change the position in the xform using the variables.

Link to comment
Share on other sites

in 12.1.33 it still works the newer build seems to fail. maybe something broke when they added the move centroid to origin button.

Yes but that's the issue. It is not broke, this is how should be working.

"This is a behaviour change from previous versions. However, the new behaviour is the correct one. The old behaviour was an unintentional side effect of some incorrect code."

Link to comment
Share on other sites

Yes but that's the issue. It is not broke, this is how should be working.

"This is a behaviour change from previous versions. However, the new behaviour is the correct one. The old behaviour was an unintentional side effect of some incorrect code."

puh, did'nt get it that You got feedback from sidefx, but I liked that side effect, too. so this goes for all variables now? they can not be channel referenced anymore?

Martin

Link to comment
Share on other sites

puh, did'nt get it that You got feedback from sidefx, but I liked that side effect, too. so this goes for all variables now? they can not be channel referenced anymore?

Martin

Yes, in my opinion the old behavior seems more logical to me. A variable such as $CEY returns 1 value, while a variable as $PT would return a list of values. Or that is what I think it is at least. So it was never confusing when to use what.

I'll hope they return it to the old behavior since it was very convenient.

Link to comment
Share on other sites

hi!

I logged this last week, and after a long email conversation they said that this is the correct behaviour (????), and it will now work this way, which imho sucks great time. Sadly I did not understood correctly the reason behind this.

I had the following answers:

"I agree that there is a behaviour change. However, the new behaviour is the correct behaviour. The old behaviour was an unintentional side effect of some incorrect code.

If this is a workflow issue, then perhaps adding a button on the Transform SOP for "Move Centroid to Origin" is in order? This allows one to non-procedurally center the input geometry by placing raw centroid value multiplied by (-1, -1, -1) into the Translate parameter."

this is sad, please don't blame that new button on me :)

Link to comment
Share on other sites

I for one vote for the old behaviour.

I also find quite strange that this was supposedly a "side effect", as it is explicitly documented in the help card, and this is the _expected_ behaviour. All other nodes' local variables work like that. Period.

Besides, the $GCX/Y/Z variable(s) (group centroid) still work, so I don't really get what they mean by "unintended behaviour". What they say is sounds pretty inconsistent.

Imre

hi!

I logged this last week, and after a long email conversation they said that this is the correct behaviour (????), and it will now work this way, which imho sucks great time. Sadly I did not understood correctly the reason behind this.

I had the following answers:

"I agree that there is a behaviour change. However, the new behaviour is the correct behaviour. The old behaviour was an unintentional side effect of some incorrect code.

If this is a workflow issue, then perhaps adding a button on the Transform SOP for "Move Centroid to Origin" is in order? This allows one to non-procedurally center the input geometry by placing raw centroid value multiplied by (-1, -1, -1) into the Translate parameter."

this is sad, please don't blame that new button on me :)

Link to comment
Share on other sites

One reason I could see for sidefx not supporting this, is that there does not appear to be a well defined way for houdini to know if a local variable is constant, or depends on something going on inside the sop that defines the variable.

If you looks at the SOP_Star example in the hdk:

http://www.sidefx.com/docs/hdk12.1/_s_o_p_2_s_o_p___star_8_c-example.html


CH_LocalVariable
SOP_Star::myVariables[] = {
    { "PT",     VAR_PT, 0 },            // The table provides a mapping
    { "NPT",    VAR_NPT, 0 },           // from text string to integer token
    { 0, 0, 0 },
};

bool
SOP_Star::evalVariableValue(fpreal &val, int index, int thread)
{
    // myCurrPoint will be negative when we're not cooking so only try to
    // handle the local variables when we have a valid myCurrPoint index.
    if (myCurrPoint >= 0)
    {
        // Note that "gdp" may be null here, so we do the safe thing
        // and cache values we are interested in.
        switch (index)
        {
            case VAR_PT:
                val = (fpreal) myCurrPoint;
                return true;
            case VAR_NPT:
                val = (fpreal) myTotalPoints;
                return true;
            default:
                /* do nothing */;
        }
    }
    // Not one of our variables, must delegate to the base class.
    return SOP_Node::evalVariableValue(val, index, thread);
}

You'll see it defines two local variables, $PT and $NPT. For the behavior you are asking for, $NPT would make sense to evaluate while $PT would not. In the definition however, there is no difference between the two.

Sidefx could build a list of special cases that would work, but then the behavior becomes unpredictable, which I generally find harder to track down.

Another option would be to add a flag to local variables to define if they are varying or not, and then all the constant ones could evaluate in channel references.

Cheers,

Koen

Edited by koen
Link to comment
Share on other sites

Channel references have always returned the value displayed in the parm GUI. Having it return 0 in only this case, when you can see a value, is confusing and inconsistent.

For example using $PT-1 in an attribcreate node will display -1 and a channel reference to that parm will return -1. There is no reason I can think of to do this, but the point is that the behavior of the channel reference is intuitive even if it isn't 'correct'. It should be up to the user to decide in what context it makes sense and the app should return the most sensible value rather than just giving up and returning 0.

Also, there are no varying local variables available in the transform SOP...

Link to comment
Share on other sites

One reason I could see for sidefx not supporting this, is that there does not appear to be a well defined way for houdini to know if a local variable is constant, or depends on something going on inside the sop that defines the variable.

The situation can get quite a lot worst than just consistency. Notice that given the way these local variables are implemented, they actually require *cooking* before they even work. Even if you relax the check, they will return default values if the node owning the local variables has not cooked yet. So often times, you won't even notice that you're screwed until rendering to the farm, when the cook order is different and suddenly the default value is returned.

Here's a contrived example to show this problem.

  1. Launch a build of H12.1.57 or older. (I'm using H12.0.634 right now.)
  2. Ctrl+Left click on the Torus shelf tool to place it at the origin
  3. Dive inside to SOPs and set the Torus' Center parameter to 5,5,0
  4. Append a Transform SOP and set the Translate parameter to -$CEX, -$CEY, -$CEZ. Turn on its display flag. Everything is good. The torus has been moved back to the origin.
  5. Copy/Paste the Transform SOP. Copy/paste a relative reference from the Translate parameter on xform1 to xform2. ie. Set xform2's Translate to ch("../xform1/tx"), ch("../xform1/ty"), ch("../xform1/tz"). Turn on its display flag.
  6. The torus is still centered. Good.
  7. Save your .hip file and reload it from the File menu.
  8. The torus is no longer at the origin. Bad.
  9. Display xform1. Hey, that works!
  10. Toggle the bypass flag on xform2 (bypass + unbypass) and then display xform2. Hey, that works again!
  11. Send the scene to the farm. A bad frame comes back WITHOUT the torus centered.

  • Like 1
Link to comment
Share on other sites

(...) Notice that given the way these local variables are implemented, they actually require *cooking* before they even work. Even if you relax the check, they will return default values if the node owning the local variables has not cooked yet. So often times, you won't even notice that you're screwed until rendering to the farm, when the cook order is different and suddenly the default value is returned.

So basically what you're saying is that you're going to remove support for these variables just because their implementation is buggy? :)

Correct me if I'm wrong, but couldn't this be implemented in a way so the node would evaluate the appropriate centroid() expressions (for the node input), and assign the results to the $CE[XYZ] variables? Something along the lines of

$CEX = centroid(opinputpath(".", 0), D_X)

$CEY = centroid(opinputpath(".", 0), D_Y)

$CEZ = centroid(opinputpath(".", 0), D_Z)

(let's assume this is pseudocode :))

Then we'd still have the variables without any evaluation inconsistency. (Assuming the centroid() functions evaluate properly). In other words, the variables would just be convenience "shortcuts" for the full expressions.

Edited by riviera
Link to comment
Share on other sites

The situation can get quite a lot worst than just consistency. Notice that given the way these local variables are implemented, they actually require *cooking* before they even work. Even if you relax the check, they will return default values if the node owning the local variables has not cooked yet. So often times, you won't even notice that you're screwed until rendering to the farm, when the cook order is different and suddenly the default value is returned.

I always assumed that a channel reference would trigger a node to cook if it hadn't already, is this not the case?

Link to comment
Share on other sites

The situation can get quite a lot worst than just consistency. Notice that given the way these local variables are implemented, they actually require *cooking* before they even work. Even if you relax the check, they will return default values if the node owning the local variables has not cooked yet. So often times, you won't even notice that you're screwed until rendering to the farm, when the cook order is different and suddenly the default value is returned.

I wasn't aware of these issues. But then using variables in the transform node is actually something to be avoided unless you are really sure you are never going to channel reference them.

Edited by kgoossens
Link to comment
Share on other sites

I always assumed that a channel reference would trigger a node to cook if it hadn't already, is this not the case?

Channel references simply evaluate the other parameter. This may or may not trigger cooking. For example, you can have ch("/obj/geo1/tx") where geo1/tx is 5. This doesn't do any cooking. If you use a centroid() expression on the other then that requires cooking.

One further note on $CEX being an alias for centroid. This also means that when you view the parameter pane for the node containing $CEX in its parameter, this will suddenly trigger cooking whereas it never did before. This does mean that old files will definitely cook in different ways regardless.

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...