-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new token node (adsk) + supporting logic. #1204
Conversation
- Fix for string resolver token addition to include looking a all parent and sibling tokens.
void PvtInterfaceConnectionCmd::updateConnectionProperties(const RtOutput& src, const RtInput& dest, RtCommandResult& /*result*/) | ||
{ | ||
// Copy token information over | ||
if (dest.isToken()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@niklasharrysson , I made this port update a virtualization. As with discussed with Jonathan before this would not be required if we could set this at port creation time but we don't have enough information (only name + type is passed).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I imagined PvtInterfaceConnectionCmd being implemented differently. This is the public API I prosed in our earlier discussion:
/// Connect a node input to the parent graph's input interface. The interface socket will be created
/// on the graph if it doesn't exists already.
void makeInterfaceConnection(const RtInput& nodeInput, const RString& graphInputName, RtCommandResult& result);
/// Connect a node output to the parent graph's output interface. The interface socket will be created
/// on the graph if it doesn't exists already.
void makeInterfaceConnection(const RtOutput& nodeOutput, const RtString& graphOutputName, RtCommandResult& result);
The socket on the nodegraph (here only given my name) would be created if it doesn't exists, and all information would be available internally to create it with the same flags as the node input it is to be connected to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could do it this way, but doesn't this repeat existing connection code ?
Also, the way things work currently is that ports are created first so it is assumed that it exsts but could add creation on demand but unsure what will occur as it could mismatch with what is created in VNN.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could still be derived from PvtConnectionCmd and use the same methods for making/breaking connections. Just that in addition it creates the interface input first if it doesn't exists, and with the correct flags set.
From a pure runtime API perspective it makes perfect sense to have such a command that encapsulates these operations into a single command, since it's a common task an API user would need.
But I understand in LookdevX it's a problem of also having to follow the rules of how VNN operates. If the interface input is created first in VNN it might be better to just use the normal connection command and then work around it in LookdevX with low-level API (setting the flags after). I didn't consider this VNN issue when proposing we create a new command for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I should have been prefaced that there is no way to create the correct port properties when it's dynamically created via VNN. There is still a "hack" outside the command code which copies over value data as well but I guess can only be done when the connection part is done (after creation). It lives outside the runtime command since it does it by setting it on the VNN port and then calling another runtime command which sets the value.
Maybe it's worth to try another go at finding some kind of proper callback from VNN to allow proper port creation.
{ | ||
return false; | ||
} | ||
//if (isToken() || output->isToken()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot to clean this. Will delete.
@@ -548,7 +548,7 @@ bool ValueElement::validate(string* message) const | |||
} | |||
if (hasInterfaceName()) | |||
{ | |||
validateRequire(isA<Input>(), res, message, "Only input elements support interface names"); | |||
validateRequire(isA<Input>() || isA<Token>(), res, message, "Only input and token elements support interface names"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allow interface exposure for tokens.
Node: token_node | ||
Non-rendering node used to hold a set of token values | ||
--> | ||
<nodedef name="ND_token_node" node="token_node" nodegroup="organization" namespace="adsk"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
adsk only for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why this node is needed? It seems it's a node just to plug tokens into, and there are not outputs and it's never used anywhere. Maybe you could give some more context why it's needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. This is the proposal to have a reusable node type which can hold a set of tokens.
It's more of a user workflow way to take a set of tokens and connect them up to as interfaces on nodegraphs and have it serializable.
There is no data flow per-se.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean it's a way for the user to create tokens on a nodegraph interface, by creating a token_node
and connecting its inputs/tokens to the nodegraphs interface to have them created there?
Because once created the tokens are part of the nodegraph interface, and their value is saved there. So after creation the token_node
is no longer needed, right?
If this is the case it seems like it's a workaround for a limitation in the UI. Would it not be better so solve this in the UI instead and add support for creating/removing/editing tokens directly on a nodegraph's interface?
If it's a temporary workaround until VNN has this supported that's totally fine, but I'm not sure it's a good long term solution for creating tokens on an interface. Just let me know if I missed something and there is more to this than just a workaround for the UI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hope this helps for clarity:
- The base assumed functionality is tokens on a nodegraph which get applied withing the scope of the nodegraph.
As with inputs, tokens are made part of the interface and hence can have variants (presets) applied to them. - The intent of the token node is keep around reusable set of tokens to apply to only within nodegraph. i.e. they are locally scoped.
2a. The initial logic was to that just the existence of the token node within a nodegraph meant to apply all the tokens.
2b. The current variant is to allow connections which means that to only use tokens from token node which have connections. Basically allow for selective reuse of tokens from a token node.
Direct creation of tokens on a nodegraph isn't currently a UI requirement (and also not possible in VNN), though is possible without UI. (Fixes for that we're in the previous check-in).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bernardkwok Thanks for the additional details. I understand the intent better now.
The fact that existence of such a node overrides the tokens set on the nodegraph is a new concept I think. And I suppose this has to be cleared with Lucasfilm later as a proposal for the spec?
I find it a little bit peculiar to have a local override inside a nodegraph that overrides something set outside (if a token is set on the nodegraph interface but also in a token_node internally). Just my 2 cents, and don't let this block the code review if you want to merge this in for now to work on it further.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The proposal I put up a little while ago and awaiting feedback.
I will try and provide more in the description and ping again. In the meantime, the unconnected case w/o a node I'll probably seperate out into a different check-in as those are fixes for already supported functionality.
interfaceInput->addTokens(resolver); | ||
} | ||
else | ||
ConstNodeGraphPtr graph = getAncestorOfType<NodeGraph>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generalize as the parent graph could have tokens which are not associated with an interface input.
Also include checking for tokens at the input level.
if (nodeDef->getNodeGroup() == ORGANIZATION_STRING) | ||
{ | ||
return false; | ||
} | ||
static string TYPE_NONE("none"); | ||
const string& typeAttribute = nodeDef->getType(); | ||
return !typeAttribute.empty() && typeAttribute != TYPE_NONE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you really need the new test for "organization" above?
Is this test for type not enough, either having an empty type or type=="none"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new node seems to have a type. Let me take a look. Perhaps I need to specifically set the type to "none" ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, if no type is set I think MaterialXCore will default to "color3" or something like that.
Update #1159
New token node definition
Tests
New test configuration:
which looks like this graphically:
The compound graph being used as the functional graph for a nodedef:
And a sample instance usage:
Results
Rendered results:
Unit test results:
token_tests.pdf