-
Notifications
You must be signed in to change notification settings - Fork 127
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
Create: Enhance instance & context changes #4375
Conversation
I think this is an improvement, but not entirely sure. I feel the code of the It could be also that the code is so undocumented making it just hard to follow why it needs to be this lengthy. Some things that stood out:
I feel that somehow it should just be way more trivial to get and store and track a value difference. |
It's object having "changes" it's not "new value" focused.
Children are not publicly available. The
You can use
Like we've discussed. If you'll tell me a way which fit more then single use-case, I'd be happy. This implementation gives ability to "only get new value" (most of current usecases), "only get changes of n-th hierarchical level" (with full old/new value), "get removed keys" (probably could be added as property), "get any changes in whatever level of values" (for massochist), ... Sometimes you may need to know the old value (e.g. because of type etc.).
|
Ok, let's step back for a bit. Can you explain why we need the nested values to begin with? Why can't we just have |
Not sure I understand |
I think there's too little information for me as to what data we're actually dealing with. I assumed something like this:
*Where originally 'instance_attributes' wasn't its own key but instead I believe those just ended up directly in the top dictionary. The original comment I made was to simplify managing changes for developers in the Creator's Some of the attributes might be special custom attributes, but some, e.g. a The simplest implementation for a DCC I could then think of would to be implement this: class Creator:
def update_changes(self, instance_changes):
for instance, changes in instance_changes:
# Store the instance attributes
for attr, change in changes["instance_attributes"].items():
old, new = change
if old is None:
# New attribute
dcc.add_attribute(instance, attr, value=new)
elif new is None:
# Deleted attribute
dcc.delete_attribute(instance, attr)
else:
# Changed attribute
if type(old) != type(new):
# Attribute type changed, recreate attribute
dcc.delete_attribute(instance, attr)
dcc.add_attribute(instance, attr, value=new)
else:
# value changed
dcc.set_attribute(instance, attr, value=new)
# Store the creator attributes
for attr, change in changes["creator_attributes"].items():
old, new = change
# Same dcc changes as above but maybe with a differen attr
# prefix?
# Store the plug-in attributes
for plugin, plugin_changes in changes["plugin_attributes"].items():
for attr, change in plugin_changes.items():
old, new = change
# Same dcc changes as above but maybe with a different attr
# prefix? I feel that's quite lengthy one and it's not managing different datatypes and not managing that e.g. This example code here assumes a completely flat data structure for old and new value, there's no nesting of dictionary values, etc. I can't even fathom how to do this if the old, new values might even be nested datastructures. The DCC code would become crazy to pull off if those were nested values even. I think if this is the length of code we'd need to write for a creator we've outdone ourselves and development will become much harder and bug-ridden because. We should think hard on how we can simplify this API and usage as much as possible before it'll become a dread to work with it and maintain. Again, it might be just my frustration with not understanding what it is we're dealing with. I can't find the documentation and there's something about this area of the code that makes it hard to parse for me. Docstrings often leave me hungry for better information - if they are there to begin with. |
There is the same issue as before. If you remove publish plugin from publish attributes you have no way how to keep the structure and pass the information.
For houdini usecase. With # Keep in mind I just made the code based on what I remember from top of my head and based on your code snippet
def update_changes(self, instance_changes):
for instance, changes in instance_changes:
for key, changed_values in changes.changes():
old_value, new_value = changed_values
# I think this is what is happening in houdini, or?
if isinstance(new_value, (dict, list)):
new_value = "JSON::{}".format(json.dumps(new_value))
if isinstance(old_value, (dict, list)):
old_value = "JSON::{}".format(json.dumps(old_value))
if new_value is None:
dcc.delete_attribute(instance, key)
elif old_value is None:
dcc.add_attribute(instance, key, value=new_value)
# Changed attribute
elif type(old_value) != type(new_value):
# Attribute type changed, recreate attribute
dcc.delete_attribute(instance, key)
dcc.add_attribute(instance, key, value=new_value)
else:
# value changed
dcc.set_attribute(instance, key, value=new_value) |
I didn't remove those though - the example include it, yes? Even from your last example I don't see why there'd be any more nesting than my initial top example data here. Yes, it would be some dicts inside for changes for plug-in attributes and for changes of creator attributes, but the attributes themselves aren't nested. I might need to step away from this for a bit and get back to it later - the frustration just seems to be a bit too high currently. 😵💫 Would be great if there were more parties using the new publisher to get some decent inputs from others who didn't build the system itself. That'd at least pinpoint whether it's just me failing to understand it or whether there's just a general lack of documentation for this to be ready for development. I feel like @maxpareschi (Houdini + USD rendering) @Tilix4 (Blender Integration) @ddesmond (Clarisse integration) might be candidates to touching that codebase |
At the end is the object of Your (based on current) changes is dictionary which contain "only differences" -> not full value. So you can't just get full new value of whole "instance_attributes" or "publish_attributes" and store it, you have to call EDITED:
|
we’re not really using that much of context stuff in Houdini, just instance subset, framerange, and instance_node name. As of today our usd render submitter is working functionally with some caveats:
Aside for this everything seem to work fine! maybe take a look at my repo before I submit a pr, seems there could be places to improve. My point is not to have too much flexibility on context and instance, it’s to have a preset data layout that can be documented and it would actually stick. Having other custom keys to contain specific plugin data should be separated from everything that is built in. So it’s easier to know what to expect. Anyways, I’m all about discussion but I need to understand what you’re doing here because right now seems like another complication on top of an already complicated structure :) |
# Conflicts: # openpype/pipeline/create/context.py
Made some changes, added docstrings and changed usages of changes in current codebase. |
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.
Tested it 3dsmax and Houdini and it seems to work
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.
Tested in AE, works
Brief description
Changes of instances and context have complex, hard to get structure. The structure did not change but instead of complex dictionaries are used objected data.
Description
This is poposal of changes data improvement for creators. Implemented
TrackChangesItem
which handles the changes for us. The item is creating changes based on old and new value and can provide information about changed keys or access to full old or new value. Can give the values on any "sub-dictionary".Used this new approach to fix change in houdini and 3ds max and also modified one aftereffects plugin using changes.
Additional info
Each object of item is creating deepcopy of both old and new data so subdictionaries are calculated dynamically on demand.