I have been banging my head against the wall a bit on this one…
The Problem
So I have bunch of Cameras that I import into maya I then compare their transforms to see if their world space transforms are a match. I then create lists of all the matches with in a Master list The output for the code looking for the matches is something like this…
A list containing lists… for example
MasterItemContainer = []
Code Runs which imports the Cameras runs comparisons between all the Cameras and loads up
MasterItemContainer now contains Lists of matches so…
for items in MasterItemContainer:
print items
output looks like this
MasterItemContainer[0] Looks like [camera_010,Camera_040,Camera,90]
MasterItemContainer[1] Looks like [camera_020,camera_080,camera_110]
etc…
So I suppose I am creating a mutli dimensional array or a list containing lists to store all the matches.
The issue I am having is that because I have to compare all the cameras to each other and store the out comes I get duplicate data for instance say I have 40 cameras to check and camera 010 and camera 080 share the same info now I have two lists with duplicate data
Bad out come if your running a check on 80 or so cameras… I feel like the real issue is the logic that I am using to load up the lists… I have to check each camera against the other cameras but once I run a check on one camera it should get removed the next time I run through the loop, but I am not sure how to do it. Any thoughts would be great
Well, I bet there are better ways, but here is a way you could just sort them out by using their transform and attributes as a dictionary key. Instead of comparing them to each other, just collect some info, and sort that way.
I am using PyMEL. And I create a function that returns a tuple of information about the camera, including transform and focalLength, etc. Use the info that makes sense to you. A tuple is hashable, so it can be used a dictionary key. (A list cannot.)
Then that tuple of info is the dictionary key. And you can sort out each camera into those keys.
import pymel.core as pm
def camera_data(cam):
# Test not only the transform, but focalLength and anything else that would distinguish a camera.
attrs = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz']
shapeAttrs = ['focalLength', 'shutterAngle']
allAttrs = [cam.getTransform().attr(eachAttr).get() for eachAttr in attrs]
allAttrs.extend(cam.attr(eachAttr).get() for eachAttr in shapeAttrs)
return tuple(allAttrs)
myCameras = {}
for cam in pm.ls(type='camera'):
cameraTransform = cam.getTransform()
newKey = camera_data(cam)
if myCameras.has_key(newKey):
# if the key exists, append
myCameras[newKey].append(cameraTransform)
else:
# otherwise, start a new list
myCameras[newKey] = [cameraTransform]
for k, v in myCameras.items():
print(k)
print(v)
You can use reverse in your list comprehension - its very powerful as it allows you to pop item thus reducing the list whilst being able to iterate over it. Roughly speaking…
names = ["a", "b", "c", "d", "e", "f", "g"] # your cameras
values = [1, 2, 1, 4, 10, 4, 2] # their values
data = zip(names, values) # zipped camera to respective values
data.reverse() # reverse the data as we'll work backwards
matched = [] # the matching data
skips = [] # during the second loop *j* we check if we have matching items and append them here
for i in reversed(range(len(data))): # iterate backwards so we can pop the values
found = [] # empty list of found matching
if data[i][0] not in skips: # only set found if it's not in skips.
found = [data[i][0]]
for j in reversed(range(len(data))):
if i != j: # skip the current index matching itself
if data[i][1] == data[j][1]: # its a match!, or not...
if data[j][0] not in skips: # only do the work if it's not in skips
found.append(data[j][0]) # append the found
skips.append(data[j][0]) # append the skips i.e. if a == b, c, d, add b, c, d to skips
if found:
matched.append(found) # only append matched if found
data.pop(i) # the *magic* pop - pull the current item
print matched
# >> [['a', 'c'], ['b', 'g'], ['d', 'f'], ['e']]