Beispiel #1
0
	def binariesPath(cls, version=None, architecture=64, language='English'):
		""" Finds the install path for various software installations.
		:param version: The version of the software. Default is None
		:param architecture: The bit type to query the registry for(32, 64). Default is 64
		:param language: Optional language that may be required for specific softwares.
		"""
		version = cls._yearForVersion.get(unicode(version), version)
		hive = 'HKEY_LOCAL_MACHINE'
		from cross3d.migrate import winregistry
		if version == None:
			# Get all of the installed versions so we can find the latest version.
			versions = winregistry.listRegKeys(hive, cls._hkeyBase, architecture=architecture)
			for v in sorted(versions, reverse=True):
				if v not in cls._ignoredVersions:
					version = v
					break
		hkey = r'{hkeyBase}\{version}'.format(hkeyBase=cls._hkeyBase, version=version)
		try:
			ret = winregistry.registryValue(hive, hkey, 'InstallPath', architecture)[0]
		except WindowsError:
			raise Exceptions.SoftwareNotInstalled('MotionBuilder', version=version, architecture=architecture, language=language)
		# If the version is not installed this will return '.', we want to return False.
		if ret:
			return os.path.normpath(ret)
		raise Exceptions.SoftwareNotInstalled('MotionBuilder', version=version, architecture=architecture, language=language)
Beispiel #2
0
    def binariesPath(cls, version=None, architecture=64, language='English'):
        """ Finds the install path for various software installations. If version is None, the default
		it will return the latest installed version of the software. Raises cross3d.Exceptions.SoftwareNotInstalled
		if the software is not installed.
		:param version: The version of the software. Default is None
		:param architecture: The bit type to query the registry for(32, 64). Default is 64
		:param language: Optional language that may be required for specific softwares.
		"""
        langId = cls._languageIDs.get(language, cls._languageIDs['English'])
        hive = 'HKEY_LOCAL_MACHINE'
        # Ensure we get a valid version number
        version = cls._versionForYear.get(unicode(version), version)
        from cross3d.migrate import winregistry
        if version == None:
            # Get all of the installed versions so we can find the latest version.
            versions = set(
                winregistry.listRegKeys(hive,
                                        cls._hkeyBase,
                                        architecture=architecture))
            # Years to ignore isnt very useful, convert them to version numbers ('14.0').
            # This allows the environment variable to remain the same for all of the software implemntations
            ignoredVersions = set([
                '{}.0'.format(cls._versionForYear[year])
                for year in cls._ignoredVersions if year in cls._versionForYear
            ])
            for v in sorted(versions, reverse=True):
                if v in versions and v not in ignoredVersions:
                    version = v.rsplit('.', 1)[0]
                    try:
                        float(version)
                    except ValueError:
                        # Not a valid version number. Most likely something like RegistryVersion19.0
                        continue
                    # Ignore all keys that don't store Installdir info.
                    hkey = cls._getHkey(version, langId)
                    try:
                        ret = winregistry.registryValue(
                            hive, hkey, 'Installdir', architecture)[0]
                        if not ret:
                            continue
                    except WindowsError:
                        continue
                    break
        dispVersion = cls._yearForVersion.get(unicode(version), version)
        hkey = cls._getHkey(version, langId)
        try:
            ret = winregistry.registryValue(hive, hkey, 'Installdir',
                                            architecture)[0]
        except WindowsError:
            raise Exceptions.SoftwareNotInstalled('Studiomax',
                                                  version=dispVersion,
                                                  architecture=architecture,
                                                  language=language)
        # If the version is not installed this will return '.', we want to return False.
        if ret:
            return os.path.normpath(ret)
        raise Exceptions.SoftwareNotInstalled('Studiomax',
                                              version=dispVersion,
                                              architecture=architecture,
                                              language=language)
Beispiel #3
0
 def __exit__(self, exec_type, exec_value, traceback):
     if hasattr(exec_value, 'message'):
         if exec_value.message in (
                 '(kInvalidParameter): Argument is a NULL pointer',
                 '(kFailure): Object does not exist'):
             # This exception is raised when you try to access a MObject via MObjectHandle that
             # no longer exists in the scene.
             raise Exceptions.InvalidNativeObject(
                 'The Native Pointer is invalid')
     # re-raise the exception
     return False
Beispiel #4
0
    def binariesPath(cls, version=None, architecture=64, language='English'):
        """ Finds the install path for various software installations. If version is None, the default
		it will return the latest installed version of the software. Raises cross3d.Exceptions.SoftwareNotInstalled
		if the software is not installed.
		:param version: The version of the software. Default is None
		:param architecture: The bit type to query the registry for(32, 64). Default is 64
		:param language: Optional language that may be required for specific softwares.
		"""
        from cross3d.migrate import winregistry
        hive = 'HKEY_LOCAL_MACHINE'
        hkey = r'Software\Autodesk\Softimage\InstallPaths'
        ret = None
        if version == None:
            # Find the latest version
            versions = winregistry.listRegKeyValues(hive,
                                                    hkey,
                                                    architecture=architecture)
            for version in sorted(versions, key=lambda i: i[0], reverse=True):
                if version[0] not in cls._ignoredVersions:
                    ret = version[1]
                    break
        else:
            version = cls._yearForVersion.get(unicode(version), version)
            try:
                ret = winregistry.registryValue(hive, hkey, unicode(version),
                                                architecture)[0]
            except WindowsError:
                raise Exceptions.SoftwareNotInstalled(
                    'Softimage',
                    version=version,
                    architecture=architecture,
                    language=language)
        # If the version is not installed this will return '.', we want to return False.
        if ret:
            return os.path.join(os.path.normpath(ret), 'Application', 'bin')
        raise Exceptions.SoftwareNotInstalled('Softimage',
                                              version=version,
                                              architecture=architecture,
                                              language=language)
Beispiel #5
0
	def generatePlayblast(
				self, 
				fileName, 
				frameRange=None, 
				resolution=None, 
				slate=None, 
				effects=True, 
				geometryOnly=True, 
				pathFormat=r'{basePath}\{fileName}.{frame}.{ext}'):
		fileName, ext = os.path.splitext(fileName)
		# Make sure a invalid file format was not requested
		if ext.replace('.', '').lower() not in self._validPlayblastFormats:
			raise Exceptions.FileFormatNotSupported('The file format {ext} is not supported by Maya'.format(ext=ext))
		
		playblastFormat = 'image'
		compression = ext.replace('.', '')
		quality = 100
		if ext.lower() == '.mov':
			playblastFormat = 'qt'
		elif ext.lower() == '.avi':
			playblastFormat = 'avi'
			compression = None
		
		if isinstance(frameRange, int):
			frameRange = FrameRange([frameRange, frameRange])
		if not frameRange:
			frameRange = self._scene.animationRange()
		# TODO: Make generating movies not require setting frame padding to 1
		padding = 1
		if not resolution:
			resolution = self._scene.renderSize()
		
		# TODO: Add support for these arguments
		if slate != None:
			# Note: this is probably how we can handle slate
			#cmds.headsUpDisplay( 'blurBurnin', section=8, block=0, blockAlignment='right', dw=50, label='This is my burnin')
			cross3d.logger.debug('slate is not implemented in Maya')
		if pathFormat != r'{basePath}\{fileName}.{frame}.{ext}':
			cross3d.logger.debug('pathFormat is not implemented in Maya')
		
		# Prepare to detect if the playblast was canceled
		formatter = '{fileName}.{frame:0%i}{ext}' % padding
		lastFrameFileName = formatter.format(fileName=fileName, frame=frameRange[1], ext=ext)
		try:
			lastFrameStartTime = os.path.getmtime(lastFrameFileName)
		except os.error:
			lastFrameStartTime = 0
		
		# to properly generate a playblast
		# pass the width/height to the playblast command
		# set the camera displayOptions
		#	set overscan to 1.0 and lock it
		# 	uncheck all options
		# set camera\Film Back
		#	Fit Resolution Gate to overscan
		# 	set proper film aspect ratio?
		# set the render resolution?
		
		
		# MCH 10/16/14 NOTE: Info on parsing playblast Display Menu if we decide to add support for that later
		#--------------------------------------------------------------------------------
		#for i in cmds.optionVar(list=True):
		#	if i.startswith('playblastShow'):
		#		print cmds.optionVar(query=i), i
		#		# Set the value
		#		cmds.optionVar( intValue=(i, False)
		#		# Update the playblast menus
		#		maya.mel.eval('updatePlayblastPluginMenus()')
		#--------------------------------------------------------------------------------
		
		cam = self.camera()
		name = cam.path()
		overscanLocked = cmds.getAttr("{name}.overscan".format(name=cam.path()), lock=True)
		if overscanLocked:
			# unlock overscan if it is locked
			cmds.setAttr("{name}.overscan".format(name=name), lock=False)
		
		# create a StateLocker object to backup the current values before setting them
		from blur3d.lib.statelockerlib import StateLocker
		with StateLocker() as stateLocker:
			# Currently the state locker isnt the most convienent to use
			def setPropertyLocker(obj, key, value):
				stateLocker.setMethodArgs(obj, obj.setProperty, partial(obj.property, key), key, value)
			
			# Set FilmBack.FitResolutionGate to Overscan
			setPropertyLocker(cam, 'filmFit', 3)
			# uncheck Display Film Gate
			setPropertyLocker(cam, 'displayFilmGate', 0)
			# uncheck Display Resolution
			setPropertyLocker(cam, 'displayResolution', 0)
			# Set overscan to 1.0
			setPropertyLocker(cam, 'overscan', 1.0)
			
			# Store and restore these settings using modelEditor
			# The key is the property to query/edit, the value is the value used while playblasting
			modelEditorOverrides = {'sel':False}
			
			# Find the current viewport so we can apply the viewport settings
			panel = cmds.getPanel(withFocus=True)
			# Check for if non-viewport panel's are active
			if not panel in cmds.getPanel(type='modelPanel'):
				panel = 'modelPanel4'
			
			if geometryOnly:
				modelEditorOverrides['nurbsSurfaces'] = True
				modelEditorOverrides['polymeshes'] = True
				modelEditorOverrides['subdivSurfaces'] = True
				# HACK: This records the viewport show options, sets them to playblast options, then
				# restores them
				# TODO: Make this load the settings from the playblast overrides
				attrs = ['nurbsCurves', 'nurbsSurfaces', 'cv', 'hulls', 'polymeshes', 
						'subdivSurfaces', 'planes', 'lights', 'cameras', 'imagePlane', 'joints', 
						'ikHandles', 'dynamics', 'deformers', 'fluids', 'hairSystems', 'follicles', 
						'nCloths', 'nParticles', 'nRigids', 'dynamicConstraints', 'locators', 
						'dimensions', 'pivots', 'handles', 'textures', 'strokes', 'motionTrails', 
						'pluginShapes', 'clipGhosts', 'greasePencils', 'manipulators', 'grid', 'hud']
				# Disable display of all of these options as long as modelEditorOverrides doesnt 
				# already contain a setting key
				updateDict = dict([(attr, False) for attr in attrs if attr not in modelEditorOverrides])
				modelEditorOverrides.update(updateDict)
				# New features in 2015
				if cross3d.application.version() > 2014 and 'particleInstancers' not in modelEditorOverrides:
					modelEditorOverrides.update(particleInstancers=False)
			
			if effects == True:
				modelEditorOverrides.update(displayTextures=True, displayLights='all')
				setPropertyLocker(self._scene, 'hardwareRenderingGlobals.ssaoEnable', 1)
				setPropertyLocker(self._scene, 'hardwareRenderingGlobals.motionBlurEnable', 1)
				setPropertyLocker(self._scene, 'hardwareRenderingGlobals.multiSampleEnable', True)
				
				# TODO: Add Camera.setDeptOfField to cross3d
				ntp = cam._nativeTypePointer
				stateLocker.setMethod(ntp, ntp.setDepthOfField, ntp.isDepthOfField, True)
				
			if effects == False:
				modelEditorOverrides.update(displayTextures=False, displayLights='default')
				setPropertyLocker(self._scene, 'hardwareRenderingGlobals.ssaoEnable', 0)
				setPropertyLocker(self._scene, 'hardwareRenderingGlobals.motionBlurEnable', 0)
				setPropertyLocker(self._scene, 'hardwareRenderingGlobals.multiSampleEnable', False)
				
				# TODO: Add Camera.setDeptOfField to cross3d
				ntp = cam._nativeTypePointer
				stateLocker.setMethod(ntp, ntp.setDepthOfField, ntp.isDepthOfField, False)
			
			# Store the current values
			modelEditorStates = {}
			for option, value in modelEditorOverrides.iteritems():
				# Store  the current value
				modelEditorStates[option] = cmds.modelEditor(panel, query=True, **{option: True})
				# Set the playblast value
				cmds.modelEditor(panel, edit=True, **{option: value})
			
#			# Uncomment this code to update the ui so you can see what options get disabled in the toolbar
#			from PyQt4.QtGui import QApplication, QMessageBox
#			QApplication.processEvents()
#			QMessageBox.question(None, 'Temp', 'update')
			
			# generate playblast
			cmds.playblast(
					width=resolution.width(), 
					height=resolution.height(), 
					startTime=frameRange.start(), 
					endTime=frameRange.end(), 
					percent=100, 
					filename=fileName, 
					showOrnaments=False, 
					format=playblastFormat, 
					compression=compression, 
					quality=quality, 
					framePadding=padding,
					viewer=False)
			
			# Restore the modelEditor options to their previous value
			for option, value in modelEditorStates.iteritems():
				cmds.modelEditor(panel, edit=True, **{option: value})
		
		if overscanLocked:
			# relock overscan
			cmds.setAttr("{name}.overscan".format(name=name), lock=True)
		
		# No way to detect if a avi or quicktime was canceled
		if ext.lower() in ('.mov', '.avi'):
			return True
		
		# If the capture was not completed we just return False.
		try:
			lastFrameEndTime = os.path.getmtime(lastFrameFileName)
			if not lastFrameStartTime < lastFrameEndTime:
					return False
		except os.error:
			return False
		return True
    def generatePlayblast(self,
                          fileName,
                          frameRange=None,
                          resolution=None,
                          slate=None,
                          effects=True,
                          geometryOnly=True,
                          pathFormat=r'{basePath}\{fileName}.{frame}.{ext}'):
        """
			Creates an unpadded JPG file sequence from the viewport for a given range.
		"""

        # Treating inputs.
        if isinstance(frameRange, int):
            frameRange = FrameRange([frameRange, frameRange])

        # Checking frame range.
        initialFrameRange = self._scene.animationRange()
        if not frameRange:
            frameRange = initialFrameRange

        # Collecting data.
        nativeCamera = self._nativeCamera()

        def genImagePath(frame=None):
            basePath, fn = os.path.split(fileName)
            pf = pathFormat
            # Deal with xsi's special number padding format
            if frame == None:
                filen = '(fn)'
                ext = '(ext)'
                # Remove any number specific formatting so we can insert a simple # for each padding digit
                pf = re.sub(r'{frame:[^}]*', r'{frame', pf)
                padding = re.findall(r'{frame:(\d+)', pathFormat)
                if padding:
                    frameNo = '#' * int(padding[0])
                else:
                    frameNo = '#'
            else:
                fileSplit = fn.split('.')
                filen = '.'.join(fileSplit[:-1])
                ext = fileSplit[-1]
                frameNo = frame
            out = pf.format(basePath=basePath,
                            fileName=filen,
                            frame=frameNo,
                            ext=ext)
            index = pathFormat.find('{ext}')
            if frame == None and index > 0 and pathFormat[index - 1] == '.':
                # strip out the file extension dot
                fileSplit = out.split('.')
                out = '.'.join(fileSplit[:-1]) + fileSplit[-1]
            return out

        firstFrameFileName = genImagePath(frameRange[0])
        lastFrameFileName = genImagePath(frameRange[1])

        try:
            firstFrameStartTime = os.path.getmtime(firstFrameFileName)
            lastFrameStartTime = os.path.getmtime(lastFrameFileName)
        except os.error:
            firstFrameStartTime = 0
            lastFrameStartTime = 0

        # Storing object states.
        self._scene.storeState()
        self.storeViewOptions()

        # Setting slate.
        if slate:
            self.setSlateText(slate)
            self.setSlateIsActive(True)
            xsi.SetValue(nativeCamera.FullName + '.camvis.currenttime', False)
        elif slate == None:
            xsi.SetValue(nativeCamera.FullName + '.camvis.currenttime', False)
        else:
            xsi.SetValue(nativeCamera.FullName + '.camvis.currenttime', True)

        # Setting regular visibility options.
        nativeCamera.Properties('Camera Visibility').Parameters(
            'gridvis').Value = False
        nativeCamera.Properties('Camera Visibility').Parameters(
            'gridaxisvis').Value = False
        nativeCamera.Properties('Camera Visibility').Parameters(
            'constructionlevel').Value = False
        nativeCamera.Properties('Camera Visibility').Parameters(
            'objannotationobjects').Value = False
        xsi.SetValue('preferences.ViewCube.show', False)

        if geometryOnly:

            # Setting geometry only visibility options.
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objpolymesh').Value = True
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objparticles').Value = True
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objinstances').Value = True
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objlights').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objcameras').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objimpgeometry').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objcurves').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objhair').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objnulls').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objctrltransfogroups').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objctrlchnjnts').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objctrlchnroots').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objctrlchneff').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objctrllattices').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objctrltextsupp').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objctrlchnjnts').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objctrlwaves').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objctrlother').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'objenvironment').Value = False
            nativeCamera.Properties('Camera Visibility').Parameters(
                'custominfo').Value = False

        # Checking resolution.
        if not resolution:
            resolution = QSize(
                xsi.GetValue("Passes.RenderOptions.ImageWidth"),
                xsi.GetValue("Passes.RenderOptions.ImageHeight"))

        # Setting the scene range. Apparently if you don't it causes an animation layer issue.
        if not initialFrameRange.contains(frameRange):
            self._scene.setAnimationRange(frameRange)

        # Set camera's picture ratio.
        camera = self.camera()
        if camera:
            pictureRatio = camera.pictureRatio()
            camera.setPictureRatio(
                float(resolution.width()) / resolution.height())

        fps = self._scene.animationFPS()

        viewportCapture = xsi.Dictionary.GetObject(
            'ViewportCapture').NestedObjects

        viewportCapture('File Name').Value = fileName
        viewportCapture('Padding').Value = os.path.basename(genImagePath())
        viewportCapture('Width').Value = resolution.width()
        viewportCapture('Height').Value = resolution.height()
        viewportCapture('Scale Factor').Value = 1
        viewportCapture('User Pixel Ratio').Value = True
        viewportCapture('Pixel Ratio').Value = 1
        viewportCapture('Frame Rate').Value = fps
        viewportCapture('Write Alpha').Value = False
        viewportCapture('Record Audio Track').Value = False
        viewportCapture('Start Frame').Value = frameRange[0]
        viewportCapture('End Frame').Value = frameRange[1]
        viewportCapture('Launch Flipbook').Value = False
        viewportCapture('Use Native Movie Player').Value = False
        viewportCapture('Movie').Value = False
        viewportCapture('OpenGL Anti-Aliasing').Value = 16 if effects else 1
        viewportCapture('Remember Last Sequence').Value = False

        letterToNumber = {"A": 1, "B": 2, "C": 3, "D": 4}
        xsi.CaptureViewport(letterToNumber[self.name], False)

        # Restoring states.
        self._scene.restoreViewOptions()
        self.restoreViewOptions()

        if camera:
            camera.setPictureRatio(pictureRatio)

        # If the famous capture Softimage bug happened we raise a specific error.
        try:
            firstFrameEndTime = os.path.getmtime(firstFrameFileName)
            if not firstFrameStartTime < firstFrameEndTime:
                raise Exceptions.OutputFailed(
                    'The playblast failed due to a native Softimage bug. Do not panic, the fix is easy. Open the regular capture window, change the format to anything. Close the window and try again.'
                )
        except os.error:
            raise Exceptions.OutputFailed(
                'The playblast failed due to a native Softimage bug. Do not panic, the fix is easy. Open the regular capture window, change the format to anything. Close the window and try again.'
            )

        # If the capture was not completed we just return False.
        try:
            lastFrameEndTime = os.path.getmtime(lastFrameFileName)
            if not lastFrameStartTime < lastFrameEndTime:
                return False
        except os.error:
            return False

        return True