Python源码示例:pymel.core.parent()
示例1
def info(self, title, description, text, align, width, height, *args):
""" Create a window showing the text info with the description about any module.
"""
# declaring variables:
self.info_title = title
self.info_description = description
self.info_text = text
self.info_winWidth = width
self.info_winHeight = height
self.info_align = align
# creating Info Window:
if cmds.window('dpInfoWindow', query=True, exists=True):
cmds.deleteUI('dpInfoWindow', window=True)
dpInfoWin = cmds.window('dpInfoWindow', title="dpAutoRig - v"+DPAR_VERSION+' - '+self.langDic[self.langName]['i013_info']+' - '+self.langDic[self.langName][self.info_title], iconName='dpInfo', widthHeight=(self.info_winWidth, self.info_winHeight), menuBar=False, sizeable=True, minimizeButton=False, maximizeButton=False)
# creating text layout:
infoColumnLayout = cmds.columnLayout('infoColumnLayout', adjustableColumn=True, columnOffset=['both', 20], parent=dpInfoWin)
cmds.separator(style='none', height=10, parent=infoColumnLayout)
infoLayout = cmds.scrollLayout('infoLayout', parent=infoColumnLayout)
if self.info_description:
infoDesc = cmds.text(self.langDic[self.langName][self.info_description], align=self.info_align, parent=infoLayout)
if self.info_text:
infoText = cmds.text(self.info_text, align=self.info_align, parent=infoLayout)
# call Info Window:
cmds.showWindow(dpInfoWin)
示例2
def donateWin(self, *args):
""" Simple window with links to donate in order to support this free and openSource code via PayPal.
"""
# declaring variables:
self.donate_title = "dpAutoRig - v"+DPAR_VERSION+' - '+self.langDic[self.langName]['i167_donate']
self.donate_description = self.langDic[self.langName]['i168_donateDesc']
self.donate_winWidth = 305
self.donate_winHeight = 300
self.donate_align = "center"
# creating Donate Window:
if cmds.window('dpDonateWindow', query=True, exists=True):
cmds.deleteUI('dpDonateWindow', window=True)
dpDonateWin = cmds.window('dpDonateWindow', title=self.donate_title, iconName='dpInfo', widthHeight=(self.donate_winWidth, self.donate_winHeight), menuBar=False, sizeable=True, minimizeButton=False, maximizeButton=False)
# creating text layout:
donateColumnLayout = cmds.columnLayout('donateColumnLayout', adjustableColumn=True, columnOffset=['both', 20], rowSpacing=5, parent=dpDonateWin)
cmds.separator(style='none', height=10, parent=donateColumnLayout)
infoDesc = cmds.text(self.donate_description, align=self.donate_align, parent=donateColumnLayout)
cmds.separator(style='none', height=10, parent=donateColumnLayout)
brPaypalButton = cmds.button('brlPaypalButton', label=self.langDic[self.langName]['i167_donate']+" - R$ - Real", align=self.donate_align, command=partial(utils.visitWebSite, DONATE+"BRL"), parent=donateColumnLayout)
#usdPaypalButton = cmds.button('usdPaypalButton', label=self.langDic[self.langName]['i167_donate']+" - USD - Dollar", align=self.donate_align, command=partial(utils.visitWebSite, DONATE+"USD"), parent=donateColumnLayout)
# call Donate Window:
cmds.showWindow(dpDonateWin)
示例3
def get_no_parent_transform(cls, ref):
"""returns the top most parent node in the given subReferences
:param ref: pm.nt.FileReference instance
"""
all_referenced_nodes = ref.nodes()
for node in all_referenced_nodes:
if isinstance(node, pm.nt.Transform):
#print('%s has parent' % node.name())
parent_node = node.getParent()
if parent_node not in all_referenced_nodes:
return node
# check sub references
sub_refs = pm.listReferences(ref)
for sub_ref in sub_refs:
no_parent_transform = cls.get_no_parent_transform(sub_ref)
if no_parent_transform:
return no_parent_transform
示例4
def setup(self):
"""setups specified object for pivot switching
"""
# if it is setup before, don't do anything
if self._isSetup:
return
if not self.is_good_for_setup():
pm.PopupError(
"the objects pivots are connected to something\n"
"THE OBJECT CANNOT BE SETUP!!!"
)
return
# create the parent constraint
self._create_future_pivot()
# create attributes for data holding
self._create_data_attribute()
# save the settings
self._save_settings()
self._isSetup = True
示例5
def rivet_per_face():
"""creates hair follicles per selected face
"""
sel_list = pm.ls(sl=1, fl=1)
follicles = []
locators = []
for face in sel_list:
# use the center of the face as the follicle position
p = reduce(lambda x, y: x + y, face.getPoints()) / face.numVertices()
obj = pm.spaceLocator(p=p)
locators.append(obj)
shape = face.node()
uv = face.getUVAtPoint(p, space='world')
follicle_transform, follicle = create_follicle(shape, uv)
pm.parent(obj, follicle_transform)
follicles.append(follicle)
return follicles, locators
示例6
def finalize_setup(self):
"""does final clean up
"""
self.check_main_control()
# group the node together
parent_group = pm.nt.Transform(name='SquashStretchBendRiggerGroup#')
pm.parent(self.main_control.getParent(), parent_group)
pm.parent(self.aim_locator1, parent_group)
if self.use_squash:
pm.parent(self.squash_handle, parent_group)
pm.parent(self.bend_handle, parent_group)
# set visibilities
self.aim_locator1.v.set(0)
if self.use_squash:
self.squash_handle.v.set(0)
self.bend_handle.v.set(0)
# as a gesture select the main control
pm.select(self.main_control)
示例7
def create_camera_space_locator(frustum_curve):
"""Creates a locator under the given frame_curve
:param frustum_curve:
:return:
"""
# create the locator
locator = pm.spaceLocator()
locator_shape = locator.getShape()
pm.parent(locator, frustum_curve, r=True)
locator.tz.set(lock=True, keyable=False)
locator.rx.set(lock=True, keyable=False)
locator.ry.set(lock=True, keyable=False)
locator.rz.set(lock=True, keyable=False)
pm.transformLimits(locator, tx=(-0.5, 0.5), etx=(True, True))
pm.transformLimits(locator, ty=(-0.5, 0.5), ety=(True, True))
locator_shape.localScaleZ.set(0)
return locator
示例8
def publish_checker(cls):
"""Opens the Publish Checker window without publishing the current
scene
"""
import functools
from anima.env import mayaEnv
m = mayaEnv.Maya()
version = m.get_current_version()
# create the publish window
from anima.ui import publish_checker
dialog = publish_checker.UI(
environment=m,
publish_callback=None,
version=version,
parent=mayaEnv.get_maya_main_window()
)
dialog.auto_delete_new_version_on_exit = False
dialog.show()
示例9
def create_local_parent(self):
"""creates local parent and axial correction group of local parent
"""
# create the localParent group
self._local_parent = pm.group(
em=True,
n=self._object.name() + "_local_parent"
)
# move it to the same place where constrainedParent is
matrix = pm.xform(self._constrained_parent, q=True, ws=True, m=True)
pm.xform(self._local_parent, ws=True, m=matrix)
# parent it to the constrained parents parent
parents = pm.listRelatives(self._constrained_parent, p=True)
if len(parents) != 0:
temp = pm.parent(self._local_parent, parents[0], a=True)
self._local_parent = temp[0]
self._local_parent = pm.nodetypes.DagNode(self._local_parent)
index = self._object.attr('pickedData.createdNodes').numElements()
self._local_parent.attr('message') >> \
self._object.attr('pickedData.createdNodes[' + str(index) + ']')
示例10
def create_stabilizer_parent(self):
"""creates the stabilizer parent
"""
# the new stabilizer parent should be at the origin of the original
# objects parent so that the keyframes of the object should not be altered
self._stabilizer_parent = pm.nodetypes.DagNode(
auxiliary.axial_correction_group(
self._object,
to_parents_origin=True
)
)
self._stabilizer_parent = pm.nodetypes.DagNode(
pm.rename(
self._stabilizer_parent,
self._object.name() + "_stabilizer_parent"
)
)
# connect it to the created nodes attribute
index = self._object.attr('pickedData.createdNodes').numElements()
self._stabilizer_parent.attr('message') >> \
self._object.attr('pickedData.createdNodes[' + str(index) + ']')
示例11
def get_weight_alias(self, parent):
"""finds weightAlias of given parent\n
if it couldn't find any it returns None
"""
if not self._is_setup:
return
parent = pm.nodetypes.DagNode(parent)
assert( isinstance(parent, pm.nodetypes.Transform) )
weightAliasList = self.get_weight_alias_list()
parentList = self.get_parent_list()
weightAlias = None
for i in range(len(parentList)):
if parentList[i] == parent:
weightAlias = weightAliasList[i]
break
return weightAlias
示例12
def add_parent_to_DAG_menu(self, parent):
"""adds the given parent to the DAG menu
oyParSw - switch to --> %PARENTNAME%
"""
# simply add "python(import oyObjectPicker as oyOP; oyOP.setObjectsParentTo( %s, %s+\".pickedData.constrainedParent[ %number% ]\" ))"
commandLabel = "oyObjectPicker - switch to --> " + parent.name()
parentIndex = self.get_parent_index(parent)
if parentIndex == -1:
return
commandString = "{\n \
int $parentIndex = " + str(parentIndex) + ";\n \
string $parentConstraint[] = `listConnections (\"%s.pickedData.parentConstraint\")`;\n \
string $parents[] = `parentConstraint -q -tl $parentConstraint[0]`;\n \
string $parentName = $parents[ $parentIndex ];\n \
python(\"import oyObjectPicker as oyOP; oyOP.set_objects_parent( '%s', '\"+$parentName+\"')\");\n \
}"
# pm.mel.source("oyAddDAGMenuCommands")
# pm.mel.oyADMC_addSpecialCommandsToObject(
# self._object.name(), commandLabel, commandString
# )
示例13
def set_parent_weight(self, parent):
"""sets the weight of the parent to 1 and the others to 0
"""
parent = pm.nodetypes.DagNode(parent)
# get the weightAlias of the parent
parent_weightAlias = self.get_weight_alias(parent)
# set the weight of the other parents to 0 and the current to 1
weightAliasList = self.get_weight_alias_list()
for weightAlias in weightAliasList:
if weightAlias == parent_weightAlias:
weightAlias.setKey(v=1, ott="step")
else:
currentWeight = weightAlias.get()
print("currentWeight = %s" % currentWeight)
if currentWeight > 0:
weightAlias.setKey(v=0, ott="step")
示例14
def set_objects_parent(object_, parent):
# import oyObjectPicker as oyOP
selList = pm.ls(sl=True)
# myPickedObj = oyOP.PickedObject(object_)
myPickedObj = PickedObject(object_)
# before seting up check if there is a cycle with the parent
if myPickedObj.check_cycle(parent):
object_ = pm.nodetypes.DagNode(object_)
parent = pm.nodetypes.DagNode(parent)
pm.PopupError(
"CYCLE ERROR!!!\n%s is a parent or special object for %s" % (
object_.name(), parent.name() ))
# do not setup any object
return
myPickedObj.setup_to_be_picked_up()
myPickedObj.add_new_parent(parent)
myPickedObj.set_active_parent(parent)
# reselect selList
pm.select(selList)
示例15
def save_as(self, shot_name, child_task_name='Previs'):
"""saves the file under the given shot name
"""
# first find the shot
from stalker import Version, Shot, Task
shot = Shot.query.filter(Shot.name == shot_name).first()
if not shot:
raise RuntimeError('No shot found with shot name: %s' % shot_name)
# get the child task
child_task = Task.query\
.filter(Task.parent == shot)\
.filter(Task.name == child_task_name)\
.first()
logged_in_user = LocalSession().logged_in_user
v = Version(task=child_task, created_by=logged_in_user)
self.m_env.save_as(v)
示例16
def set_zero_joint(self):
#Removes Zero Joint from Joint Chain
pm.joint(self.jointChain[0], e=True, zso=True, oj='xyz', sao='xup')
self.zeroJoint = self.jointChain[0]
self._zeroPos = pm.dt.Point(pm.getAttr(self._zeroJoint.translate))
self.jointChain.remove(self.jointChain[0])
self.jointPos.remove(self.jointPos[0])
pm.joint(self.jointChain[1], e=True, zso=True, oj='xyz', sao='yup')
for i in range(1, len(self.jointChain)):
pm.joint(self.jointChain[i], e=True, zso=True, oj='xyz', sao='yup')
#sets Start End Num Of Joints again
self._numOfJoints = len(self._jointChain)
#Orient Zero Joint
temporalGroup = DrawNode(Shape.transform, 'temporalGroup')
pm.parent(self.startJoint, temporalGroup.drawnNode)
print(pm.getAttr(self.zeroJoint.jointOrient))
pm.setAttr(self.zeroJoint.jointOrientX, 0)
pm.parent(self.startJoint, self.zeroJoint)
temporalGroup.delete()
示例17
def create_axialCor(self):
# Create Axial Correction group
if self._axialCor is not None:
temp_grp = pm.group(self.drawnNode, n=(self._axialCor + "_#"))
self.ofsGrp.append(temp_grp)
else:
name = (self.drawnNode + "_axialCor")
self._axialCor = self._draw(Shape.transform,
(name))
pm.delete(pm.parentConstraint(self.drawnNode, self.axialCor, mo=0))
pm.parent(self._drawnNode, self._axialCor)
#pm.delete(self.create_parentConst(self.drawnNode, self.axialCor))
#pm.parent(self._drawnNode, self.axialCor)
# Create Point Constrain
示例18
def createCurveFromJoint(joints, name="curve", ibtCVNum=0, degree=3):
"""
Create a nurbs curve along the given joints
:param joints: `list` list of joint nodes
:param name: `string` name of the built surface
:param ibtCVNum: `int` number of cv points added inbetween the joint position
:param degree: `int` nurbs surface degree
:return: `PyNode` result curve
"""
jntPos = [jnt.getTranslation(space="world") for jnt in joints]
cvPos = []
if ibtCVNum>0:
for i in range(len(jntPos)-1):
cvPos.append(jntPos[i])
ratio = (jntPos[i+1]-jntPos[i])/(ibtCVNum+1.0)
for j in range(1, ibtCVNum+1):
cvPos.append(jntPos[i]+ratio*j)
cvPos.append(jntPos[-1])
else:
cvPos = jntPos
auxCrv = pm.curve(p=cvPos, d=degree, n=name)
pm.rebuildCurve(auxCrv, ch=0, rpo=1, rt=0, end=1, kep=1, kr=0, kcp=0,
kt=0, s=len(cvPos)-1, d=degree)
pm.parent(auxCrv, w=1)
return auxCrv
示例19
def dpARLoadingWindow():
""" Just create a Loading window in order to show we are working to user when calling dpAutoRigSystem.
"""
loadingString = "Loading dpAutoRigSystem v%s ... " %DPAR_VERSION
print loadingString,
path = os.path.dirname(__file__)
randImage = random.randint(0,7)
clearDPARLoadingWindow()
cmds.window('dpARLoadWin', title="dpAutoRigSystem", iconName='dpAutoRig', widthHeight=(285, 203), menuBar=False, sizeable=False, minimizeButton=False, maximizeButton=False)
cmds.columnLayout('dpARLoadLayout')
cmds.image('loadingImage', image=(path+"/Icons/dp_loading_0%i.png" %randImage), backgroundColor=(0.8, 0.8, 0.8), parent='dpARLoadLayout')
cmds.text('versionText', label=loadingString, parent='dpARLoadLayout')
cmds.showWindow('dpARLoadWin')
示例20
def copy(self, mesh):
self.cluster_list = []
self.point_dict = {}
self.cls_weight_dict = {}
dummy = common.TemporaryReparent().main(mode='create')
common.TemporaryReparent().main(mesh, dummyParent=dummy, mode='cut')
cluster = cmds.ls(cmds.listHistory(mesh), type='cluster', l=True)
for cls in cluster:
set_node = cmds.ls(cmds.listHistory(cls, f=True), type='objectSet', l=True)[0]
cmds.select(set_node)
vertices = cmds.ls(sl=True)
vertices = cmds.filterExpand(vertices, sm=31)
cmds.select(vertices, r=True)
try:
weights = cmds.percent(cls, q=True, v=True)
print weights
#値が取れないときアンドゥするとなぜか直ることがある
except Exception as e:
print e.message
cmds.delete(cls)
cmds.undo()
set_node = cmds.ls(cmds.listHistory(cls, f=True), type='objectSet', l=True)[0]
vertices = cmds.ls(sl=True)
vertices = cmds.filterExpand(vertices, sm=31)
cmds.select(vertices, r=True)
weights = cmds.percent(cls, q=True, v=True)
self.cluster_list.append(cls)
self.cls_weight_dict[cls] = weights
self.point_dict[cls] = vertices
common.TemporaryReparent().main(mesh, dummyParent=dummy, mode='parent')#コピーのおわったメッシュの子供を元に戻す
common.TemporaryReparent().main(dummyParent=dummy, mode='delete')#ダミー親削除
return self.point_dict, self.cls_weight_dict
示例21
def duplicate_with_skin(nodes, parentNode=None):
#親子付けがあってもエラーはかないように修正
print nodes
# リストタイプじゃなかったらリストに変換する
if not isinstance(nodes, list):
nodes = [nodes]
dupObjs = []
for node in nodes:
#子供のノード退避用ダミーペアレントを用意
dummy = common.TemporaryReparent().main(mode='create')
common.TemporaryReparent().main(node,dummyParent=dummy, mode='cut')
#複製
dup = cmds.duplicate(node)[0]
#ウェイト転送メソッドをSimpleWeightコピペに変更
weight.SimpleWeightCopyPaste().main(node, mode='copy', saveName=__name__, weightFile=node)
weight.SimpleWeightCopyPaste().main(dup, mode='paste', saveName=__name__, weightFile=node)
#親子付けを戻す
common.TemporaryReparent().main(node,dummyParent=dummy, mode='parent')
#ダミーペアレントを削除
common.TemporaryReparent().main(dummyParent=dummy, mode='delete')
if parentNode is not None:
cmds.parent(dup, parentNode)
dupObjs.append(dup)
return dupObjs
#シーン内、もしくは入力メッシュ内にゼロポリゴンオブジェクトがあるかどうか調べる関数
示例22
def addCnsCurve(parent, name, centers, degree=1):
"""Create a curve attached to given centers. One point per center
Arguments:
parent (dagNode): Parent object.
name (str): Name
centers (list of dagNode): Object that will drive the curve.
degree (int): 1 for linear curve, 3 for Cubic.
Returns:
dagNode: The newly created curve.
"""
# rebuild list to avoid input list modification
centers = centers[:]
if degree == 3:
if len(centers) == 2:
centers.insert(0, centers[0])
centers.append(centers[-1])
elif len(centers) == 3:
centers.append(centers[-1])
points = [datatypes.Vector() for center in centers]
node = addCurve(parent, name, points, False, degree)
applyop.gear_curvecns_op(node, centers)
return node
示例23
def addCurve(parent,
name,
points,
close=False,
degree=3,
m=datatypes.Matrix()):
"""Create a NurbsCurve with a single subcurve.
Arguments:
parent (dagNode): Parent object.
name (str): Name
positions (list of float): points of the curve in a one dimension array
[point0X, point0Y, point0Z, 1, point1X, point1Y, point1Z, 1, ...].
close (bool): True to close the curve.
degree (bool): 1 for linear curve, 3 for Cubic.
m (matrix): Global transform.
Returns:
dagNode: The newly created curve.
"""
if close:
points.extend(points[:degree])
knots = range(len(points) + degree - 1)
node = pm.curve(n=name, d=degree, p=points, per=close, k=knots)
else:
node = pm.curve(n=name, d=degree, p=points)
if m is not None:
node.setTransformation(m)
if parent is not None:
parent.addChild(node)
return node
示例24
def createCurveFromCurve(srcCrv, name, nbPoints, parent=None):
"""Create a curve from a curve
Arguments:
srcCrv (curve): The source curve.
name (str): The new curve name.
nbPoints (int): Number of control points for the new curve.
parent (dagNode): Parent of the new curve.
Returns:
dagNode: The newly created curve.
"""
if isinstance(srcCrv, str) or isinstance(srcCrv, unicode):
srcCrv = pm.PyNode(srcCrv)
length = srcCrv.length()
parL = srcCrv.findParamFromLength(length)
param = []
increment = parL / (nbPoints - 1)
p = 0.0
for x in range(nbPoints):
# we need to check that the param value never exceed the parL
if p > parL:
p = parL
pos = srcCrv.getPointAtParam(p, space='world')
param.append(pos)
p += increment
crv = addCurve(parent, name, param, close=False, degree=3)
return crv
示例25
def get_selected_reference_path(cls):
"""prints the path of the selected reference path
"""
selection = pm.ls(sl=1)
if len(selection):
node = selection[0]
ref = node.referenceFile()
if ref:
print(ref.path)
parent_ref = ref.parent()
while parent_ref is not None:
print(parent_ref.path)
parent_ref = parent_ref.parent()
示例26
def fix_reference_paths(cls):
"""Fixes reference paths that are not using environment vars
"""
# list current scene references
from anima.env import mayaEnv
m_env = mayaEnv.Maya()
current_version = m_env.get_current_version()
all_refs = pm.listReferences(recursive=True)
refs_with_wrong_prefix = []
for ref in all_refs:
if '$REPO' not in ref.unresolvedPath():
parent = ref.parent()
if parent:
refs_with_wrong_prefix.append(parent)
ref_paths = [ref.path for ref in refs_with_wrong_prefix]
for ref_path in ref_paths:
version = m_env.get_version_from_full_path(ref_path)
if version:
m_env.open(version, force=True, skip_update_check=True)
pm.saveFile()
if pm.env.sceneName() != current_version.absolute_full_path:
m_env.open(current_version, force=True, skip_update_check=True)
示例27
def unload_unselected_references(cls):
"""unloads the references that is not related to the selected objects
"""
import copy
selected_references = []
# store selected references
for node in pm.ls(sl=1):
ref = node.referenceFile()
if ref is not None and ref not in selected_references:
selected_references.append(ref)
temp_selected_references = copy.copy(selected_references)
# store parent references
for ref in temp_selected_references:
parent_ref = ref.parent()
if parent_ref is not None \
and parent_ref not in selected_references:
while parent_ref is not None:
if parent_ref not in selected_references:
selected_references.append(parent_ref)
parent_ref = parent_ref.parent()
# now unload all the other references
for ref in reversed(pm.listReferences(recursive=1)):
if ref not in selected_references:
ref.unload()
示例28
def instance(self, source_transform_node):
"""instances the given nodes hierarchy
"""
# duplicate the given node
# then replace the instanceable nodes with instances
# find instanceable nodes in the node and dupNode
source_hierarchy = self.walk_hierarchy(source_transform_node)
# if there is no node in the sourceHierarchy just return
# the instance of the given node
if len(source_hierarchy) < 1:
dup_node = pm.duplicate(source_transform_node, ilf=1, rc=True)[0]
pm.select(dup_node)
return
dup_node = pm.duplicate(source_transform_node, rc=True)[0]
dup_hierarchy = self.walk_hierarchy(dup_node)
for i, node in enumerate(dup_hierarchy):
shape = node.getShape()
if shape is not None and isinstance(shape,
tuple(self._instanceables)):
# instance the corresponding sourceNode
source_node = source_hierarchy[i]
new_instance_node = pm.duplicate(source_node, ilf=True)[0]
pm.parent(new_instance_node, node.getParent(), r=False)
pm.delete(node)
pm.select(dup_node)
return dup_node
示例29
def setup_look_at(camera):
"""sets up the look at locator for the given camera
"""
# just create a locator under the camera
# and move it to -10
loc = pm.spaceLocator(n=camera.name() + "vertigo_loc#")
# create a new attribute under the camera
global vertigo_attr_name
camera_shape = camera.getShape()
if not camera.hasAttr(vertigo_attr_name):
pm.addAttr(camera, ln=vertigo_attr_name, at="message")
# connect the message attribute of the locator to the camera
loc.message >> camera.attr(vertigo_attr_name)
pm.parent(loc, camera)
loc.t.set(0, 0, -10)
loc.r.set(0, 0, 0)
# lock locators tx, ty and rotate channels
loc.tx.lock()
loc.ty.lock()
loc.r.lock()
示例30
def setup_vertigo(camera):
"""sets up the vertigo for the given camera
"""
# camera should have the vertigo locator
global vertigo_attr_name
global vertigo_global_attr_name
vertigo_loc = camera.attr(vertigo_attr_name).inputs()[0]
# get the initial distance of the vertigo locator
z1 = vertigo_loc.tz.get()
f1 = camera.focalLength.get()
# create a locator under world to hold the locator at the same place
world_loc = pm.spaceLocator(n=camera.name() + "vertigo_space_loc#")
# connect world_loc to camera
if not camera.hasAttr(vertigo_global_attr_name):
pm.addAttr(camera, ln=vertigo_global_attr_name, at="message")
world_loc.message >> camera.attr(vertigo_global_attr_name)
# position the world_loc to the correct place
pm.parent(world_loc, vertigo_loc)
world_loc.t.set(0, 0, 0)
world_loc.r.set(0, 0, 0)
pm.parent(world_loc, w=True)
# unlock vertigo_loc's translate
vertigo_loc.tx.unlock()
vertigo_loc.ty.unlock()
pm.pointConstraint(world_loc, vertigo_loc)
# create the expression
expr_str = camera.name() + ".focalLength = (" + vertigo_loc.name() + \
".tz / " + str(z1) + ") * " + str(f1) + ";"
expr = pm.expression(s=expr_str)