# Compare difference between two networks

## Recommended Posts

I have two scenes where one has had some changes. Is there a way to easily tell what changes have been made

Many thanks

##### Share on other sites

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

##### Share on other sites

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

##### Share on other sites

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.

##### Share on other sites

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

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

message = print_added_or_removed_nodes(a) + '\n' + \
return message

networks = hou.selectedNodes()
net_b_name = networks[1].name()
network_a, network_b = node_names(networks)

nodes_removed = network_a.issuperset(network_

r = 'removed'

elif nodes_removed:
else:

```

Let me know if this works out for you.

• 2

##### Share on other sites

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.

##### Share on other sites

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

##### Share on other sites

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

##### Share on other sites

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

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

message = print_added_or_removed_nodes(a) + '\n' + \

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_removed = network_a.issuperset(network_
shared_nodes = list(network_a.intersection(network_)

parm_dicts = get_parms(networks, shared_nodes)

r = 'removed'

elif nodes_removed:
else:

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.

• 3
• 1

##### Share on other sites

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.

##### Share on other sites

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

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

message = print_added_or_removed_nodes(a) + '\n' + \

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_removed = network_a.issuperset(network_b)
shared_nodes = list(network_a.intersection(network_b))

parm_dicts = get_parms(networks, shared_nodes)

r = 'removed'

elif nodes_removed:
else:

hou.ui.displayMessage(compare_parms(parm_dicts, shared_nodes))```

Edited by p2or
python
• 1

##### Share on other sites

@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!

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account