def imp_option_list(self, *args): del self.listOfImagePlanes[:] self.imgplanesOptionMenu.clear() # creates a list of existing image planes and update Image Plane Option menu self.listOfImagePlanes = [i for i in pm.ls(type='imagePlane')] _logger.debug("imp_option_list: %s" % self.listOfImagePlanes) if len(self.listOfImagePlanes) > 0: self.currentImgPlane = pm.imagePlane(self.listOfImagePlanes[0], query=True, name=True) for item in self.listOfImagePlanes: _logger.debug('imp is %s' % pm.imagePlane(item, query=True, name=True)) imp = pm.imagePlane(item, query=True, name=True) pm.menuItem(l=imp[0], parent=self.imgplanesOptionMenu) # set active menu item to current image plane _logger.debug('Current Imageplane: %s' % self.currentImgPlane) pm.optionMenu(self.imgplanesOptionMenu, e=True, value="%s" % self.currentImgPlane[0]) else: pm.menuItem(l="No Image Planes", parent=self.imgplanesOptionMenu) self.currentImgPlane = False
def on_browse_btn(self, *args): # Image browse button callback handler impFile = '' impFile = pm.fileDialog2(fileMode=1) if impFile is None or len(impFile) < 1: return else: print('ipm: importing new image plane %s ' % cmds.file(impFile, query=True, type=True)) currentCamera = pm.optionMenu(self.cameraOptionMenu, q=1, v=1) #get name for new imageplane impName = self.nameFromFile(pathname=impFile) self.currentImgPath = impFile[0] self.currentImgPlane = (pm.imagePlane(width=100, height=50, name=impName))[1] _logger.debug('Imported. file name is %s ' % impFile) pm.imagePlane(self.currentImgPlane, e=True, camera=currentCamera) _logger.debug('Set camera to %s ' % currentCamera) try: pm.imagePlane(self.currentImgPlane, e=True, fileName=self.currentImgPath) except: pass _logger.debug('Imp file has mov is %s ' % impFile[0].rsplit('.')[-1] == "mov") if impFile[0].rsplit('.')[-1] == 'mov': _logger.debug('Setting to .mov %s ' % self.currentImgPlane) pm.setAttr('%s.type' % self.currentImgPlane, 2) self.imp_option_list() #update option menu pm.textFieldButtonGrp(self.ImpPathTxt, e=True, text=self.currentImgPath) #update edit image plane frame try: #close import window pm.deleteUI(self.importWindow, window=True) #rebuild parent window self.create() except: sys.stderr.write( 'Error rebuilding Interface after image file import. Check name and file type of image.' )
def create_camera_and_plane(json_path, image_path): """ Create a camera and image plane given a json with data generated from fSpy. :param str json_path: full path to the json. :param str image_path: full or relative path to the image to use. :return: A dictionary containing the newly created nodes in the following format: {'camera': (camera_transform, camera_shape), 'image_plane': (image_transform, image_shape), 'root': group} :rtype: dict """ with open(json_path) as json_file: data = json.load(json_file) # Group for all the created items. group = pm.group(em=True, n='projected_camera_grp_001') # Applying the matrix transformations onto a camera matrix_rows = [['in00', 'in10', 'in20', 'in30'], ['in01', 'in11', 'in21', 'in31'], ['in02', 'in12', 'in22', 'in32'], ['in03', 'in13', 'in23', 'in33']] # Creating a camera, 4x4 matrix and decompose-matrix, then setting up the connections. camera_transform, camera_shape = pm.camera() pm.parent(camera_transform, group) matrix = pm.createNode('fourByFourMatrix', n='cameraTransform_fourByFourMatrix') decompose_matrix = pm.createNode('decomposeMatrix', n='cameraTransform_decomposeMatrix') pm.connectAttr(matrix.output, decompose_matrix.inputMatrix) pm.connectAttr(decompose_matrix.outputTranslate, camera_transform.translate) pm.connectAttr(decompose_matrix.outputRotate, camera_transform.rotate) # Setting the matrix attrs onto the 4x4 matrix. for i, matrix_list in enumerate(data['cameraTransform']['rows']): for value, attr in zip(matrix_list, matrix_rows[i]): pm.setAttr(matrix.attr(attr), value) # creating an image plane for the camera image_transform, image_shape = pm.imagePlane(camera=camera_transform) pm.setAttr(image_shape.imageName, image_path, type='string') # Cleanup pm.delete([matrix, decompose_matrix]) for attr in ['translate', 'rotate', 'scale']: for ax in ['X', 'Y', 'Z']: camera_transform.attr(attr + ax).lock() image_transform.attr(attr + ax).lock() # Returning all the newly created items in case someone wants to grab and use them later. return { 'camera': (camera_transform, camera_shape), 'image_plane': (image_transform, image_shape), 'root': group }
def image_plane(path, **kwargs): """ Creates an image plane from the path provided. Width and height optional but highly recommended. Returns new image plane """ width_height = kwargs.setdefault('widthHeight', (100, 100)) image_plane_xform = py.imagePlane(width=width_height[0], height=width_height[1])[0] py.setAttr("%s.imageName" % image_plane_xform, path, type="string") reference_layer(image_plane_xform) return image_plane_xform
def on_retarget_btn(self, *args): sourcecam = pm.imagePlane(self.currentImgPlane, q=1, camera=1) targetcam = pm.optionMenu(self.cameraRetargetMenu, q=1, v=1) confirm = pm.confirmDialog( title='Confirm', message='Retargeting image plane %s from %s to %s' % (self.currentImgPlane, sourcecam, targetcam), button=['Yes', 'No'], defaultButton='Yes', cancelButton='No', dismissString='No') if confirm == 'Yes': moverTranslation = None moverScale = None #retarget mover if pm.objExists('%s_mover' % self.currentImgPlane[0]): mover = '%s_mover' % self.currentImgPlane[0] moverTranslation = pm.xform(mover, q=1, translation=1) moverScale = pm.xform(mover, q=1, scale=1) #pm.parent(mover, pm.listRelatives(targetcam, p=1)) #pm.xform(mover, translation=moverTranslation) #pm.xform(mover, scale=moverScale) pm.delete('%s_mover' % self.currentImgPlane[0]) pm.delete('%s_moveroffset' % self.currentImgPlane[0]) print 'ipm: retargeting image plane %s from %s to %s' % ( self.currentImgPlane, sourcecam, targetcam) pm.imagePlane(self.currentImgPlane, e=1, camera=targetcam) #self.translateImageplane(moverTranslation, moverScale) self.createMover(moverTranslation, moverScale) return targetcam #except: #sys.stderr.write('Error retargeting image plane %s from %s to %s'%(self.currentImgPlane, sourcecam, targetcam)) else: return None
def on_imp_change(self, *args): # image plane option menu update handler itemnumber = pm.optionMenu(self.imgplanesOptionMenu, q=True, select=True) currentImpItem = pm.imagePlane(self.listOfImagePlanes[(itemnumber - 1)], query=True, name=True) # update currenImpPlane self.currentImgPlane = currentImpItem self.updateImagePlaneEditSliders()
def createImgPln(): global imgOp global imgDep global curCam global ImgPln global fileNm global pLoc #comfirmDialog for checking if ImgPln in the scene allTransNd = pm.ls(type='transform',fl=True) isImgPln = [] for trans in allTransNd: if trans == 'ImagePlane_Parent_Loc': isImgPln.append(trans) if len(isImgPln) >= 1: cfmAnswer = pm.confirmDialog( title='Confirm', message='Delete Image Plane?', button=['Yes','No'], defaultButton='Yes', cancelButton='No', dismissString='No' ) if cfmAnswer == 'Yes': cleanupImgPln() createImgPln() elif len(isImgPln) == 0: #image plane opacty and offset from camera imgOp = 1 imgDep = 10 #get current camera curCam = pm.modelPanel(pm.getPanel(wf=True),q=True,cam=True) #select image and creat imagePlane and setup fileNm = pm.fileDialog2(ds=0,fm=1,cap='open',okc='Select Image') ImgPln = pm.imagePlane(fn=fileNm[0],lookThrough=curCam,maintainRatio=1) pm.setAttr(ImgPln[1]+'.displayOnlyIfCurrent',True) pm.setAttr(ImgPln[0]+'.translateZ',-pm.getAttr(curCam+'.translateZ')/3+-imgDep) pm.setAttr(ImgPln[1]+'.alphaGain',imgOp) pm.setAttr(ImgPln[1]+'.textureFilter',1) #aligh to the camera #create locator to be the parent and then create parent constraint pLoc = pm.spaceLocator(name='ImagePlane_Parent_Loc') pm.parent(ImgPln[0],pLoc) LocCons = pm.parentConstraint(curCam,pLoc) pm.setAttr(pLoc+'Shape.template',1) pm.setAttr(LocCons+'.template',1)
def load(self, context, name, namespace, data): new_nodes = [] image_plane_depth = 1000 asset = context['asset']['name'] namespace = namespace or lib.unique_namespace( asset + "_", prefix="_" if asset[0].isdigit() else "", suffix="_", ) # Getting camera from selection. selection = pc.ls(selection=True) if len(selection) > 1: QtWidgets.QMessageBox.critical( None, "Error!", "Multiple nodes selected. Please select only one.", QtWidgets.QMessageBox.Ok) return if len(selection) < 1: QtWidgets.QMessageBox.critical(None, "Error!", "No camera selected.", QtWidgets.QMessageBox.Ok) return relatives = pc.listRelatives(selection[0], shapes=True) if not pc.ls(relatives, type="camera"): QtWidgets.QMessageBox.critical(None, "Error!", "Selected node is not a camera.", QtWidgets.QMessageBox.Ok) return camera = selection[0] try: camera.displayResolution.set(1) camera.farClipPlane.set(image_plane_depth * 10) except RuntimeError: pass # Create image plane image_plane_transform, image_plane_shape = pc.imagePlane( camera=camera, showInAllViews=False) image_plane_shape.depth.set(image_plane_depth) image_plane_shape.imageName.set( context["representation"]["data"]["path"]) start_frame = pc.playbackOptions(q=True, min=True) end_frame = pc.playbackOptions(q=True, max=True) image_plane_shape.frameOffset.set(1 - start_frame) image_plane_shape.frameIn.set(start_frame) image_plane_shape.frameOut.set(end_frame) image_plane_shape.useFrameExtension.set(1) if context["representation"]["name"] == "mov": # Need to get "type" by string, because its a method as well. pc.Attribute(image_plane_shape + ".type").set(2) # Ask user whether to use sequence or still image. if context["representation"]["name"] == "exr": # Ensure OpenEXRLoader plugin is loaded. pc.loadPlugin("OpenEXRLoader.mll", quiet=True) reply = QtWidgets.QMessageBox.information( None, "Frame Hold.", "Hold image sequence on first frame?", QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Cancel) if reply == QtWidgets.QMessageBox.Ok: pc.delete( image_plane_shape.listConnections(type="expression")[0]) image_plane_shape.frameExtension.set(start_frame) new_nodes.extend([ image_plane_transform.longName().split("|")[-1], image_plane_shape.longName().split("|")[-1] ]) for node in new_nodes: pc.rename(node, "{}:{}".format(namespace, node)) return containerise(name=name, namespace=namespace, nodes=new_nodes, context=context, loader=self.__class__.__name__)
def on_camlookthrough_btn(self, *args): pm.lookThru(pm.imagePlane(self.currentImgPlane, q=1, camera=1))
def on_camselect_btn(self, *args): pm.select(pm.imagePlane(self.currentImgPlane, q=1, camera=1))
def on_views_change_current(self, *args): pm.imagePlane(self.currentImgPlane[0], e=1, showInAllViews=0)
for trans in allTransNd: if trans == 'ImagePlane_Parent_Loc': isImgPln.append(trans) if len(isImgPln) == 0: cfmAnswer = pm.confirmDialog( title='Confirm', message='Create New Image Plane?', button=['Yes','No'], defaultButton='Yes', cancelButton='No', dismissString='No' ) if cfmAnswer == 'Yes': createImgPln() elif len(isImgPln) >= 1: pa.mel.eval('AEimagePlaneBrowser "AEassignImageCB imagePlaneShape1.type imagePlaneShape1.imageName" imagePlaneShape1') pm.setAttr(ImgPln[0]+'.translateX',0) pm.setAttr(ImgPln[0]+'.translateY',0) #HUD ''' imgWH = pm.imagePlane('imagePlaneShape1',q=True,width=True,height=True) imgScale = pm.getAttr('imagePlane1'+'.s') imgWth = imgWH[0]*imgScale[0] imgHigh = imgWH[1]*imgScale[0] pm.xform('nurbsCircle1',r=True,os=True,t=(imgWth/2,imgHigh/2,0)) #constraint control's x,y to the image plane's x,y pm.parentConstraint('imagePlane1','nurbsCircle1',st='z',mo=True) #constraint image plane's z to the control's z pm.parentConstraint('nurbsCircle1','imagePlane1',st=['x','y'],mo=True) #cursor hover menu #http://tech-artists.org/forum/showthread.php?419-popUpMenu-mel-notes-quot-dagObjectHit-quot #More Image Planes to the camera
def createMover(self, translation=None, scale=None): imp = self.currentImgPlane[0] # create new mover or get existing if pm.objExists('%s_mover' % self.currentImgPlane[0]): mover = pm.PyNode('%s_mover' % self.currentImgPlane[0]) pm.select(mover) ### TODO check if camera-imageplane has changed and if so rebuild connections return mover elif pm.getAttr('%s.sizeX' % imp, lock=True) or pm.getAttr( '%s.sizeY' % imp, lock=True) or pm.getAttr('%s.offsetX' % imp, lock=True): sys.stderr.write( 'imp: Error creating Mover. Make sure imageplane %s scale and offset are not locked.' % imp) pm.select(imp) return None else: print 'imp: Creating mover for %s' % self.currentImgPlane[0] #mover = pm.spaceLocator(name='%s_mover'%self.currentImgPlane[0]) mover = pm.createNode('transform', name='%s_mover' % self.currentImgPlane[0]) #parent to camera and align to image plane camera = pm.listRelatives(pm.imagePlane(imp, q=1, camera=1), p=True) pm.parent(mover, camera) if translation is None: mover.tx.set(pm.getAttr('%s.offsetX' % imp) * 10) mover.ty.set(pm.getAttr('%s.offsetY' % imp) * 10) else: pm.xform(mover, translation=translation) #set distance from camera relative to focal length mover.tz.set(-1 * (pm.getAttr('%s.focalLength' % camera[0].name()) / 2)) if scale is None: mover.scale.set(pm.getAttr('%s.sizeX' % imp), pm.getAttr('%s.sizeY' % imp), 1) else: pm.xform(mover, scale=scale) mover.rotate.set([0, 0, 0]) #connect imageplane to mover moveroffset = pm.shadingNode('multiplyDivide', asUtility=1, n='%s_moveroffset' % imp) moveroffset.operation.set(2) moveroffset.input2X.set(10) moveroffset.input2Y.set(10) mover.tx >> moveroffset.input1X mover.ty >> moveroffset.input1Y pm.connectAttr('%s.outputX' % moveroffset, '%s.offsetX' % imp, f=1) pm.connectAttr('%s.outputY' % moveroffset, '%s.offsetY' % imp, f=1) pm.connectAttr('%s.scaleX' % mover, '%s.sizeX' % imp, f=1) pm.connectAttr('%s.scaleY' % mover, '%s.sizeY' % imp, f=1) pm.select(mover) return mover
def load(self, context, name, namespace, data): import pymel.core as pc new_nodes = [] image_plane_depth = 1000 # Getting camera from selection. selection = pc.ls(selection=True) if len(selection) > 1: QtWidgets.QMessageBox.critical( None, "Error!", "Multiple nodes selected. Please select only one.", QtWidgets.QMessageBox.Ok ) return if len(selection) < 1: QtWidgets.QMessageBox.critical( None, "Error!", "No camera selected.", QtWidgets.QMessageBox.Ok ) return relatives = pc.listRelatives(selection[0], shapes=True) if not pc.ls(relatives, type="camera"): QtWidgets.QMessageBox.critical( None, "Error!", "Selected node is not a camera.", QtWidgets.QMessageBox.Ok ) return camera = selection[0] camera.displayResolution.set(1) camera.farClipPlane.set(image_plane_depth * 10) # Create image plane image_plane_transform, image_plane_shape = pc.imagePlane( camera=camera, showInAllViews=False ) image_plane_shape.depth.set(image_plane_depth) image_plane_shape.imageName.set( context["representation"]["data"]["path"] ) start_frame = pc.playbackOptions(q=True, min=True) end_frame = pc.playbackOptions(q=True, max=True) image_plane_shape.frameOffset.set(1 - start_frame) image_plane_shape.frameIn.set(start_frame) image_plane_shape.frameOut.set(end_frame) image_plane_shape.useFrameExtension.set(1) if context["representation"]["name"] == "mov": # Need to get "type" by string, because its a method as well. pc.Attribute(image_plane_shape + ".type").set(2) # Ask user whether to use sequence or still image. if context["representation"]["name"] == "exr": reply = QtWidgets.QMessageBox.information( None, "Frame Hold.", "Hold image sequence on first frame?", QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Cancel ) if reply == QtWidgets.QMessageBox.Ok: pc.delete( image_plane_shape.listConnections(type="expression")[0] ) image_plane_shape.frameExtension.set(start_frame) # Ensure OpenEXRLoader plugin is loaded. pc.loadPlugin("OpenEXRLoader.mll", quiet=True) new_nodes.extend( [image_plane_transform.name(), image_plane_shape.name()] ) return new_nodes
def importAsset(self, iAObj=None): component = ftrack.Component(iAObj.componentId) start, end = self.getStartEndFrames(component, iAObj) first_image = iAObj.filePath % start new_nodes = [] # Image plane if iAObj.options["importType"] == "Image Plane": # Getting camera new_camera = False if iAObj.options["attachCamera"]: cam = pm.ls(selection=True)[0] else: cam = pm.createNode("camera") new_camera = True if iAObj.options["renameCamera"]: asset_name = component.getVersion().getAsset().getName() pm.rename(cam.getTransform(), asset_name) if new_camera: new_nodes.extend([cam.name(), cam.getTransform().name()]) if iAObj.options["resolutionGate"]: cam.displayResolution.set(1) cam.farClipPlane.set(iAObj.options["imagePlaneDepth"] * 10) # Create image plane visibility = True option = "Hidden from other cameras" if iAObj.options["imagePlaneVisibility"] == option: visibility = False image_plane_transform, image_plane_shape = pm.imagePlane( camera=cam, fileName=first_image, showInAllViews=visibility) image_plane_shape.useFrameExtension.set(1) image_plane_shape.depth.set(iAObj.options["imagePlaneDepth"]) new_nodes.extend( [image_plane_transform.name(), image_plane_shape.name()]) # Create ground plane if iAObj.options["createGround"]: ground_transform, ground_shape = pm.polyPlane( name="ground", height=iAObj.options["groundSize"], width=iAObj.options["groundSize"]) ground_shader = pm.shadingNode("lambert", asShader=True) visiblity = iAObj.options["groundVisibility"] / 100 ground_shader.transparency.set(visiblity, visiblity, visiblity) pm.select(ground_transform) pm.hyperShade(assign=ground_shader.name()) new_nodes.extend([ ground_transform.name(), ground_shape.name(), ground_shader.name() ]) # File Node if iAObj.options["importType"] == "File Node": file_node = pm.shadingNode("file", asTexture=True) file_node.fileTextureName.set(first_image) file_node.useFrameExtension.set(1) exp = pm.shadingNode("expression", asUtility=True) exp.expression.set(file_node.name() + ".frameExtension=frame") new_nodes.extend([file_node.name(), exp.name()]) # Connecting file node to color management in 2016+ if pm.objExists("defaultColorMgtGlobals"): colMgmtGlob = pm.PyNode("defaultColorMgtGlobals") mapping = { "cmEnabled": "colorManagementEnabled", "configFileEnabled": "colorManagementConfigFileEnabled", "configFilePath": "colorManagementConfigFilePath", "workingSpaceName": "workingSpace" } for key, value in mapping.iteritems(): src_name = colMgmtGlob.name() + "." + key dst_name = file_node.name() + "." + value pm.PyNode(src_name) >> pm.PyNode(dst_name) texture = None if iAObj.options["fileNodeType"] != "Single Node": texture = pm.shadingNode("place2dTexture", asUtility=True) src_name = texture.name() + ".outUV" dst_name = file_node.name() + ".uvCoord" pm.PyNode(src_name) >> pm.PyNode(dst_name) src_name = texture.name() + ".outUvFilterSize" dst_name = file_node.name() + ".uvFilterSize" pm.PyNode(src_name) >> pm.PyNode(dst_name) connections = [ "rotateUV", "offset", "noiseUV", "vertexCameraOne", "vertexUvThree", "vertexUvTwo", "vertexUvOne", "repeatUV", "wrapV", "wrapU", "stagger", "mirrorU", "mirrorV", "rotateFrame", "translateFrame", "coverage" ] for connection in connections: src_name = texture.name() + "." + connection dst_name = file_node.name() + "." + connection pm.PyNode(src_name) >> pm.PyNode(dst_name) new_nodes.append(texture.name()) if iAObj.options["fileNodeType"] == "Projection": projection = pm.shadingNode("projection", asUtility=True) texture3d = pm.shadingNode("place3dTexture", asUtility=True) src_name = file_node.name() + ".outColor" dst_name = projection.name() + ".image" pm.PyNode(src_name) >> pm.PyNode(dst_name) src_name = texture3d.name() + ".worldInverseMatrix" dst_name = projection.name() + ".placementMatrix" pm.PyNode(src_name) >> pm.PyNode(dst_name) new_nodes.extend([projection.name(), texture3d.name()]) self.newData = set(new_nodes) self.oldData = set() self.linkToFtrackNode(iAObj)
def importAsset(self, iAObj=None): component = ftrack.Component(iAObj.componentId) start, end = self.getStartEndFrames(component, iAObj) new_nodes = [] # Image plane if iAObj.options["importType"] == "Image Plane": movie_path = iAObj.filePath % start # Getting camera new_camera = False if iAObj.options["attachCamera"]: cam = pm.ls(selection=True)[0] else: cam = pm.createNode("camera") new_camera = True if iAObj.options["renameCamera"]: asset_name = component.getVersion().getAsset().getName() pm.rename(cam.getTransform(), asset_name) if new_camera: new_nodes.extend([cam.name(), cam.getTransform().name()]) if iAObj.options["resolutionGate"]: cam.displayResolution.set(1) cam.farClipPlane.set(iAObj.options["imagePlaneDepth"] * 10) # Create image plane visibility = True option = "Hidden from other cameras" if iAObj.options["imagePlaneVisibility"] == option: visibility = False image_plane_transform, image_plane_shape = pm.imagePlane( camera=cam, showInAllViews=visibility) image_plane_shape.depth.set(iAObj.options["imagePlaneDepth"]) # Need to get "type" by string, because its a method as well. pm.Attribute(image_plane_shape + ".type").set(2) image_plane_shape.imageName.set(movie_path) image_plane_shape.useFrameExtension.set(1) new_nodes.extend( [image_plane_transform.name(), image_plane_shape.name()]) # Create ground plane if iAObj.options["createGround"]: ground_transform, ground_shape = pm.polyPlane( name="ground", height=iAObj.options["groundSize"], width=iAObj.options["groundSize"]) ground_shader = pm.shadingNode("lambert", asShader=True) visiblity = iAObj.options["groundVisibility"] / 100 ground_shader.transparency.set(visiblity, visiblity, visiblity) pm.select(ground_transform) pm.hyperShade(assign=ground_shader.name()) new_nodes.extend([ ground_transform.name(), ground_shape.name(), ground_shader.name() ]) self.newData = set(new_nodes) self.oldData = set() self.linkToFtrackNode(iAObj)
def load(self, context, name, namespace, data): import pymel.core as pm new_nodes = [] image_plane_depth = 1000 asset = context['asset']['name'] namespace = namespace or lib.unique_namespace( asset + "_", prefix="_" if asset[0].isdigit() else "", suffix="_", ) # Get camera from user selection. camera = None default_cameras = ["frontShape", "perspShape", "sideShape", "topShape"] cameras = [ x for x in pm.ls(type="camera") if x.name() not in default_cameras ] camera_names = {x.getParent().name(): x for x in cameras} camera_names["Create new camera."] = "create_camera" window = CameraWindow(camera_names.keys()) window.exec_() camera = camera_names[window.camera] if camera == "create_camera": camera = pm.createNode("camera") if camera is None: return try: camera.displayResolution.set(1) camera.farClipPlane.set(image_plane_depth * 10) except RuntimeError: pass # Create image plane image_plane_transform, image_plane_shape = pm.imagePlane( camera=camera, showInAllViews=False) image_plane_shape.depth.set(image_plane_depth) image_plane_shape.imageName.set( context["representation"]["data"]["path"]) start_frame = pm.playbackOptions(q=True, min=True) end_frame = pm.playbackOptions(q=True, max=True) image_plane_shape.frameOffset.set(1 - start_frame) image_plane_shape.frameIn.set(start_frame) image_plane_shape.frameOut.set(end_frame) image_plane_shape.frameCache.set(end_frame) image_plane_shape.useFrameExtension.set(1) movie_representations = ["mov", "preview"] if context["representation"]["name"] in movie_representations: # Need to get "type" by string, because its a method as well. pm.Attribute(image_plane_shape + ".type").set(2) # Ask user whether to use sequence or still image. if context["representation"]["name"] == "exr": # Ensure OpenEXRLoader plugin is loaded. pm.loadPlugin("OpenEXRLoader.mll", quiet=True) message = ("Hold image sequence on first frame?" "\n{} files available.".format( len(context["representation"]["files"]))) reply = QtWidgets.QMessageBox.information( None, "Frame Hold.", message, QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Cancel) if reply == QtWidgets.QMessageBox.Ok: pm.delete( image_plane_shape.listConnections(type="expression")[0]) image_plane_shape.frameExtension.set(start_frame) new_nodes.extend([ image_plane_transform.longName().split("|")[-1], image_plane_shape.longName().split("|")[-1] ]) for node in new_nodes: pm.rename(node, "{}:{}".format(namespace, node)) return containerise(name=name, namespace=namespace, nodes=new_nodes, context=context, loader=self.__class__.__name__)