How to find the highest end value of nla strips in a group of objects?

I have a group of objects in my scene that have animated materials. I've converted the material animations to NLA strips, and am trying to find the highest value in the list of end frames that the script is supposed to generate.

The goal is to have it so that when I have an object selected, the script searches the material NLA strip end values for all of the objects in the selected objects group, and finds the highest value in all of the strips.

Currently, it seems to print the end values for all of the strips, rather than finding the highest value among them. For example, in the blend I attached below, the highest value for the strips in the group of objects is 112, but it prints all of the values when the script is run.

Does anyone know what the problem could be?

import bpy
from random import choice

scene = bpy.context.scene
o = bpy.context.object
random_group = choice(o.users_group)
obs = random_group.objects[:]
myMaterials = bpy.data.materials

for o in obs:

myMaterials = o.data.materials

for material in myMaterials:
# Get all materials of currently selected object (if any)
if o.type == 'CURVE' or o.type == 'MESH':

if o.data.materials:

nla_strips = []

if  material.animation_data is not None:

track =  material.animation_data.nla_tracks

if  material.animation_data and  material.animation_data.nla_tracks:

for track in  material.animation_data.nla_tracks:

for strip in track.strips:
nla_strips.append((strip, strip.mute))

myset = set([strip.frame_end])
print (max(myset))


The first issue is that with myset = set([strip.frame_end]) you are creating a new set each time the loop runs and only ever adding one value. When you call max() is finds there is one value, which it then picks as the max (as there are no other values in myset to compare it to).

The second issue - the reason why it is printing out all the values instead of just one - is that aside from the previous issue, the print() statement is inside the main loop, which is why it prints each time.

So you need to:

1. Store myset outside the for loop and add values to it in the loop (instead of overwriting it).
2. Look for the max value once the loop has finished.

The new code:

import bpy
from random import choice

scene = bpy.context.scene
o = bpy.context.object
random_group = choice(o.users_group)
obs = random_group.objects[:]
myMaterials = bpy.data.materials

myset = []

for o in obs:
myMaterials = o.data.materials
for material in myMaterials:
# Get all materials of currently selected object (if any)
if o.type == 'CURVE' or o.type == 'MESH':
if o.data.materials:
if material.animation_data is not None:
track = material.animation_data.nla_tracks
if material.animation_data and material.animation_data.nla_tracks:
for track in material.animation_data.nla_tracks:
for strip in track.strips:
#myset = set([strip.frame_end])
#print (max(myset))
myset.append(strip.frame_end)

print(max(myset))


So, instead of making a set and immediately printing it, I append the strip.frame_end value into a list (as there doesn't seem to be a need for a set, though I have kept the name myset) and print the max of it at the end.

• I'd just discovered lists and was trying to use list([myset]) and append values but I'd gotten the same result. To think the solution to the issue was as simple as placing myset outside of the for loop. Thanks! This problem had me stumped for days. – Dassie May 20 '19 at 17:12