Announcements

Starting in December, we will archive content from the community that is 10 years and older. This FAQ provides more information.

Lock attributes on camera

minniemischief
Participant
Participant

Lock attributes on camera

minniemischief
Participant
Participant

Hi everyone,

 

I have no real knowledge of Python but I usually get by scrounging bits and pieces off of scripts I find online, bits and pieces that are echoed in the Script Editor, etc. However, now I'm trying to continue writing something and I am stuck. I need some help! Please be gentle with me because again, and it may be obvious; I have no idea what I'm doing 😛

 

The situation is as follows: I have multiple scenes that already have a custom camera in them, but it has a different name in each scene, so I want to find whatever is not one of Maya's standard cameras, and make adjustments to it. So far I've been able to do everything I want to do except lock that camera's transforms. Because I start out with the Shape node and change attributes there, after that I want to get to the transform node and lock the translation and rotation. 

 

Here's what I have, currently:

 

import maya.cmds as mc

mc.setAttr("defaultResolution.width", 1280)
mc.setAttr("defaultResolution.height", 720)
mc.setAttr ("hardwareRenderingGlobals.multiSampleEnable", 1)

for each_cam_shp in mc.ls(type="camera"):

    exclude_cams=["frontShape","perspShape","sideShape","topShape"]

    if each_cam_shp not in exclude_cams:

	mc.setAttr(each_cam_shp+".displayFilmGate", True)
	mc.setAttr(each_cam_shp+".filmFit", 3)
	mc.setAttr(each_cam_shp+".overscan", 1)
	mc.setAttr(each_cam_shp+".displayGateMaskOpacity", 0.99)
	mc.setAttr(each_cam_shp+".displayGateMaskColor", 0,0,0, type='double3')


    #here's where I need some help
    each_cam_tr = mc.listRelatives(each_cam_shp, type='transform', parent=True, fullPath=True)
    
    for each_cam_tr in each_cam_shp:
    
        exclude_mayacams=["front","persp","side","top"]
        
        if each_cam_tr not in exclude_mayacams:
            
            mc.setAttr(each_cam_tr+".tx", l=True)

 

The last part returns a RuntimeError: setAttr: No object matches name: f.tx

 

I don't understand where it's getting "f" from, and I'm tired of trying to figure it all out by myself. Someone please help me?

0 Likes
Reply
Accepted solutions (1)
417 Views
6 Replies
Replies (6)

Kahylan
Advisor
Advisor

Hi!

 

So there are a few problems with your code. I understand that you are just "Frankensteining" it together, so this is more meant as useful information for the next script than as critisim or anything.

 

1) The biggest problem is the one that causes your Error. Which stems from the fact that you redefine "each_cam_tr" in the condition of your for-loop and using as local variable to iterate through the current "each_cam_shp", python treats strings as lists of letters when they are at the highest level of a iteration statement like a forloop, so it tries to change the variable for the first letter of your cam shape.

 

2) The second exlusion statement is redundant, you are already excluding the shapes of the standard cams in your first if statement, so the listRelatives command will never return a standard cams transform. So I removed that.

 

3) You are excluding your standard cams direcly by name. addressing nodes by directly referring to a static string is not good form and generally should be avoided. Now in this case it isn't too bad since the standard cams can't be renamed, so this would work in like 90% of cases. But there are exceptions that could cause problems, for example if there was a user generated cam called "front" inside a group it would also be excluded. A more dynamic way to find the standard cams is to look for undeletable cams that can't change their locked status by listing all undeletable cams and all locked cams that can change their status and then excluding the latter list from the first.

 

So the code after the changes would look like this:

import maya.cmds as mc

mc.setAttr("defaultResolution.width", 1280)
mc.setAttr("defaultResolution.height", 720)
mc.setAttr ("hardwareRenderingGlobals.multiSampleEnable", 1)

#getting default cameras
exclude_cams = mc.ls(type = "camera", ud = True)
user_locked_cams = mc.ls(type = "camera", ln = True)

for c in exclude_cams:
    print(c)
    if c in user_locked_cams:
        exclude_cams.remove(c)
        
for each_cam_shp in mc.ls(type="camera"):
    
	if each_cam_shp not in exclude_cams:

		mc.setAttr(each_cam_shp+".displayFilmGate", True)
		mc.setAttr(each_cam_shp+".filmFit", 3)
		mc.setAttr(each_cam_shp+".overscan", 1)
		mc.setAttr(each_cam_shp+".displayGateMaskOpacity", 0.99)
		mc.setAttr(each_cam_shp+".displayGateMaskColor", 0,0,0, type='double3')


		each_cam_tr = mc.listRelatives(each_cam_shp, type='transform', parent=True, fullPath=True)
		
		for cam in each_cam_tr:
		
			mc.setAttr(cam +".tx", l=True)

 

I hope this helps!

minniemischief
Participant
Participant

Hey @Kahylan ,

 

Thank you so much for taking the time to reply to me and trying to explain what I was doing wrong, I appreciate it! Hoewever, your solution didn't actually work. No resolution gate etc. was set and my camera transforms weren't locked.. I test this by opening an empty scene, creating a new perspective camera and then running the code. The new cam should have the resolution gate, be locked etc. but that's not what's happening. Any more ideas?

0 Likes

Kahylan
Advisor
Advisor

What version of Maya are you on?

 

Because the code I posted works fine in Maya 2022. I attatched a video of doing the same test and everything works fine.

 

Also the only transform that gets locked is .tx and thats because that is the only one your code wanted to lock, all the other transforms are left untouched so far I just assumed thats what you wanted since you specifically singled out "tx". If you wanted to lock all tranforms, the last part of your code should be:

 

		for cam in each_cam_tr:
		
			mc.setAttr(cam +".t", l=True)
			mc.setAttr(cam +".r", l=True)
			mc.setAttr(cam +".s", l=True)

 

 

minniemischief
Participant
Participant

@Kahylan I'm in Maya 2020.4, perhaps that's why? 

0 Likes

Kahylan
Advisor
Advisor
Accepted solution

I just tried the script in my 2018 version that I have installed on another pc and it indeed doesn't work. The problem is that the "ud" flag in the ls command (atleast in 2018) doesn't work and also returns deletable objects, so the way I was doing my exclusion was just excluding all cameras...
But I acutally found a more elegant way of doing the exclusion anyways, the way I did it before was working but quite hacky. I realised that the camera command has a querriable "startupCamera" status that returns True if a camera is a startup cam. So all I needed to do was only run the first if statement if this flag returned false on the camera.

 

Here's the new code, it worked in 2018 and 2022.3, hopefully also in the version you are using.

import maya.cmds as mc

mc.setAttr("defaultResolution.width", 1280)
mc.setAttr("defaultResolution.height", 720)
mc.setAttr ("hardwareRenderingGlobals.multiSampleEnable", 1)
        
for each_cam_shp in mc.ls(type="camera"):
    
	if mc.camera(each_cam_shp, q = True,sc = True) == False:

		mc.setAttr(each_cam_shp+".displayFilmGate", True)
		mc.setAttr(each_cam_shp+".filmFit", 3)
		mc.setAttr(each_cam_shp+".overscan", 1)
		mc.setAttr(each_cam_shp+".displayGateMaskOpacity", 0.99)
		mc.setAttr(each_cam_shp+".displayGateMaskColor", 0,0,0, type='double3')


		each_cam_tr = mc.listRelatives(each_cam_shp, type='transform', parent=True, fullPath=True)
		
		for cam in each_cam_tr:
		
			mc.setAttr(cam +".tx", l=True)

 

I hope it helps!

minniemischief
Participant
Participant

@Kahylan this works perfectly, thank you so much!

0 Likes