spev Posted November 18, 2015 Share Posted November 18, 2015 I have two scenes where one has had some changes. Is there a way to easily tell what changes have been made Many thanks Quote Link to comment Share on other sites More sharing options...
lukeiamyourfather Posted November 18, 2015 Share Posted November 18, 2015 There's a "as code" function which you could just compare differences in text at that point which there are many ways of doing. http://www.sidefx.com/docs/houdini15.0/hom/hou/Node#asCode Probably lots of ways to skin this cat but that's the first that comes to mind. 2 Quote Link to comment Share on other sites More sharing options...
jrockstad Posted November 18, 2015 Share Posted November 18, 2015 If you're comfortable with Python, the first thing that comes to mind for me is creating sets out of lists of the nodes in the networks and using the set boolean operations to compare them. The basic logic would be: if network_a.issuperset(network_: net_diff = network_a.difference(network_ elif network_b.issuperset(network_a): net_diff = network_b.difference(network_a) else: net_diff_a = network_a.difference(network_ net_diff_b = network_b.difference(network_a) Where network_a and network_b are the sets of node names. I'll see if I can cook up something a bit more substantial for you later on. 1 Quote Link to comment Share on other sites More sharing options...
spev Posted November 18, 2015 Author Share Posted November 18, 2015 Thanks jrockstad for your kind answer. I am not greatly familiar with python.. I was hoping there was a built in tool like diff on cmd line. Quote Link to comment Share on other sites More sharing options...
jrockstad Posted November 19, 2015 Share Posted November 19, 2015 (edited) Wrote up a little script, create a custom shelf tool and paste this in the Script tab to use it: # Houdini Python shelf tool for comparing node networks # Usage: Select first network, shift-select second network, launch tool def node_names(networks): node_lists = () for network in networks: nodes = network.glob('*') node_lists += (set([node.name() for node in nodes]),) return node_lists def print_added_or_removed_nodes(a_or_r): if a_or_r == 'added': nodes = list(network_b.difference(network_a)) message = "Nodes added to {}: \n".format(net_b_name) else: nodes = list(network_a.difference(network_) message = "Nodes removed in {}: \n".format(net_b_name) if nodes != []: nodes.sort() for node in nodes: message += node + '\n' return message def print_added_and_removed_nodes(): message = print_added_or_removed_nodes(a) + '\n' + \ print_added_or_removed_nodes(r) return message networks = hou.selectedNodes() net_b_name = networks[1].name() network_a, network_b = node_names(networks) nodes_added = network_b.issuperset(network_a) nodes_removed = network_a.issuperset(network_ a = 'added' r = 'removed' if nodes_added: hou.ui.displayMessage(print_added_or_removed_nodes(a)) elif nodes_removed: hou.ui.displayMessage(print_added_or_removed_nodes(r)) else: hou.ui.displayMessage(print_added_and_removed_nodes()) Let me know if this works out for you. Edited November 20, 2015 by jrockstad 2 Quote Link to comment Share on other sites More sharing options...
lukeiamyourfather Posted November 19, 2015 Share Posted November 19, 2015 That's a nice script, but it doesn't tell you if things like parameters on nodes have changed. Using the "as code" method looks at everything in the networks. Using a list of nodes could work depending on the needs of the workflow. Quote Link to comment Share on other sites More sharing options...
jrockstad Posted November 20, 2015 Share Posted November 20, 2015 That's a nice script, but it doesn't tell you if things like parameters on nodes have changed. Using the "as code" method looks at everything in the networks. Using a list of nodes could work depending on the needs of the workflow. Ah, yeah, looking back at the original post it's not perfectly clear if he's referring to differences in the overall node network, on parameters, or both. It seems like my current script could be a good jumping off point in any case, since it already has the ability to filter the list of nodes to check based on if they're shared between both networks. I definitely had fun writing that script so I'll see if I can tweak it a bit. 1 Quote Link to comment Share on other sites More sharing options...
spev Posted November 22, 2015 Author Share Posted November 22, 2015 Guys... Amazing answers.. Thank you both very much... I was hoping to find out the following .. Extra nodes, parameter changes and possibly dependencies too... Basically as much info as poss... Thanks again I will try both options Quote Link to comment Share on other sites More sharing options...
jrockstad Posted November 26, 2015 Share Posted November 26, 2015 Modified version of my script, now including parameter changes: # Houdini Python shelf tool for comparing node networks # Prints changes in networks followed by changes in parameters # Usage: Select first network, shift-select second network, launch tool # Network comparison functions def get_node_names(networks): node_lists = () for network in networks: nodes = network.children() node_lists += (set([node.name() for node in nodes]),) return node_lists def print_added_or_removed_nodes(a_or_r): if a_or_r == 'added': nodes = list(network_b.difference(network_a)) message = "Nodes added to '{}': \n\n".format(net_b_name) else: nodes = list(network_a.difference(network_) message = "Nodes removed in '{}': \n\n".format(net_b_name) if nodes != []: nodes.sort() for node in nodes: message += " " + node + '\n' return message def print_added_and_removed_nodes(): message = print_added_or_removed_nodes(a) + '\n' + \ print_added_or_removed_nodes(r) return message # Parameter comparison functions def get_parms(networks, shared_nodes): parm_dicts = () for network in networks: node_parms = {} nodes = network.children() for node in nodes: if node.name() in shared_nodes: parm_tuple = [(node.name(), node.parmTuples())] node_parms.update(parm_tuple) parm_dicts += (node_parms,) return parm_dicts def compare_parms(parm_dicts, shared_nodes): message = "" a_parms, b_parms = parm_dicts for node in shared_nodes: a_parm_vals = [] b_parm_vals = [] parm_labels = [] for parm_tuple in a_parms[node]: for parm in parm_tuple: a_parm_vals.append(parm.evalAsString()) parm_labels.append(parm.name()) for parm_tuple in b_parms[node]: for parm in parm_tuple: b_parm_vals.append(parm.evalAsString()) if a_parm_vals != b_parm_vals: message += "Changed parameters in node {}:".format(node) + '\n\n' for val in range(0, len(parm_labels) - 1): if a_parm_vals[val] != b_parm_vals[val]: message += " Value in '{}' for '{}': {}".format \ (net_a_name, parm_labels[val], a_parm_vals[val]) + \ '\n' + \ " Value in '{}' for '{}': {}".format \ (net_b_name, parm_labels[val], b_parm_vals[val]) + \ '\n\n' return message # Script start networks = hou.selectedNodes() net_a_name = networks[0].name() net_b_name = networks[1].name() network_a, network_b = get_node_names(networks) nodes_added = network_b.issuperset(network_a) nodes_removed = network_a.issuperset(network_ shared_nodes = list(network_a.intersection(network_) parm_dicts = get_parms(networks, shared_nodes) a = 'added' r = 'removed' if nodes_added: hou.ui.displayMessage(print_added_or_removed_nodes(a)) elif nodes_removed: hou.ui.displayMessage(print_added_or_removed_nodes(r)) else: hou.ui.displayMessage(print_added_and_removed_nodes()) hou.ui.displayMessage(compare_parms(parm_dicts, shared_nodes)) There's definitely a lot of room to polish it up, and in particular I would like to add: - Option for user to choose whether they want to see node changes, parameter changes, or both - Option to print output to file - More efficient / readable output, especially for parameters ...but for now, it does exactly what it says on the tin. 4 1 Quote Link to comment Share on other sites More sharing options...
kris Posted October 18, 2019 Share Posted October 18, 2019 @jrockstad Hi I tried to use the code as is its throwing syntax errors Quote SyntaxError: ('invalid syntax', ('tool_6', 23, 15, ' message = "Nodes removed in \'{}\': \\n\\n".format(net_b_name)\n')) I tried fixing it but got another syntax error.... (network_) to (network_b)) Quote SyntaxError: ('invalid syntax', ('tool_6', 94, 12, 'shared_nodes = list(network_a.intersection(network_)\n')) I tried fixing the second error nodes_removed = network_a.issuperset(network_ shared_nodes = list(network_a.intersection(network_) to... nodes_removed = network_a.issuperset(network_b) shared_nodes = list(network_a.intersection(network_b)) Now the code runs but shows empty message window... Can you have a another look at this code...It will be very useful... Thanks, Rama. Quote Link to comment Share on other sites More sharing options...
p2or Posted April 27, 2020 Share Posted April 27, 2020 (edited) Many thanks @jrockstad. Fixed some minor issues to make it work for h18+. For convenience I also created a gist here. # Houdini Python shelf tool for comparing node networks # Prints changes in networks followed by changes in parameters # Original Author: @jrockstad # https://forums.odforce.net/topic/24410-compare-difference-between-two-networks/ # Usage: Select first network, shift-select second network, launch tool # ----------------------------------------------- # Network comparison functions # ----------------------------------------------- def get_node_names(networks): node_lists = () for network in networks: nodes = network.children() node_lists += (set([node.name() for node in nodes]),) return node_lists def print_added_or_removed_nodes(a_or_r): message = '' if a_or_r == 'added': nodes = list(network_b.difference(network_a)) message = "Nodes added to '{}': \n\n".format(net_b_name) else: nodes = list(network_a.difference(network_b)) message = "Nodes removed in '{}': \n\n".format(net_b_name) if nodes != []: nodes.sort() for node in nodes: message += " {}".format(node) return message def print_added_and_removed_nodes(): message = print_added_or_removed_nodes(a) + '\n' + \ print_added_or_removed_nodes(r) return message # ----------------------------------------------- # Parameter comparison functions # ----------------------------------------------- def get_parms(networks, shared_nodes): parm_dicts = () for network in networks: node_parms = {} nodes = network.children() for node in nodes: if node.name() in shared_nodes: parm_tuple = [(node.name(), node.parmTuples())] node_parms.update(parm_tuple) parm_dicts += (node_parms,) return parm_dicts def compare_parms(parm_dicts, shared_nodes): message = '' a_parms, b_parms = parm_dicts for node in shared_nodes: a_parm_vals = [] b_parm_vals = [] parm_labels = [] for parm_tuple in a_parms[node]: for parm in parm_tuple: a_parm_vals.append(parm.evalAsString()) parm_labels.append(parm.name()) for parm_tuple in b_parms[node]: for parm in parm_tuple: b_parm_vals.append(parm.evalAsString()) if a_parm_vals != b_parm_vals: message += "Changed parameters in node {}:".format(node) + '\n\n' for val in range(0, len(parm_labels) - 1): if a_parm_vals[val] != b_parm_vals[val]: message += " Value in '{}' for '{}': {}".format \ (net_a_name, parm_labels[val], a_parm_vals[val]) + \ '\n' + \ " Value in '{}' for '{}': {}".format \ (net_b_name, parm_labels[val], b_parm_vals[val]) + \ '\n\n' return message # ----------------------------------------------- # Init # ----------------------------------------------- networks = hou.selectedNodes() net_a_name = networks[0].name() net_b_name = networks[1].name() network_a, network_b = get_node_names(networks) nodes_added = network_b.issuperset(network_a) nodes_removed = network_a.issuperset(network_b) shared_nodes = list(network_a.intersection(network_b)) parm_dicts = get_parms(networks, shared_nodes) a = 'added' r = 'removed' if nodes_added: hou.ui.displayMessage(print_added_or_removed_nodes(a)) elif nodes_removed: hou.ui.displayMessage(print_added_or_removed_nodes(r)) else: hou.ui.displayMessage(print_added_and_removed_nodes()) hou.ui.displayMessage(compare_parms(parm_dicts, shared_nodes)) Edited April 27, 2020 by p2or python 1 Quote Link to comment Share on other sites More sharing options...
Valent Posted January 7, 2022 Share Posted January 7, 2022 @jrockstad, @p2or, Hi, is it possible to modify this script for it to be able to compare the network and parameter changes but between two different scenes? Thanks! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.