Jump to content

Aaron Powell

Members
  • Posts

    11
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by Aaron Powell

  1. I usually have a folder in my projects for saving python scripts and other useful tools that aren't necessarily linked to a specific scene or asset. Scripts to set up global render settings, or a tool made specifically for the job, or whatever.

    I'm not sure the best way to store them in ftrack now that I'm starting to transition projects over (asset build vs folder etc). My guess is that the answer is something along the lines of, "whatever works for you". But I'm curious to see how people are already handling this kind of thing.

  2. import logging
    
    import ftrack_api
    
    import sys
    import pprint
    
    import ftrack_connect.application
    
    class ApplicationStore(ftrack_connect.application.ApplicationStore):
        '''Store used to find and keep track of available applications.'''
    
        def _discoverApplications(self):
            '''Return a list of applications that can be launched from this host.'''
            applications = []
    
            if sys.platform == 'darwin':
                prefix = ['/', 'Applications']
    
                applications.extend(self._searchFilesystem(
                    expression=prefix + [
                        'Blender*', 'Blender.app'
                    ],
                    label='Blender {version}',
                    applicationIdentifier='blender_{version}'
                ))
    
            elif sys.platform == 'win32':
                prefix = ['C:\\', 'Program Files.*']
    
                applications.extend(self._searchFilesystem(
                    expression=(
                        prefix +
                        ['Blender Foundation', 'Blender*', 'blender.exe']
                    ),
                    label='Blender {version}',
                    applicationIdentifier='blender_{version}'
                ))
    
            self.logger.debug(
                'Discovered applications:\n{0}'.format(
                    pprint.pformat(applications)
                )
            )
    
            return applications
        
    
    
    
    class BlenderAction(object):
        '''Launch Blender action.'''
    
        # Unique action identifier.
        identifier = 'blender-launch-action'
    
        def __debug(self, message):
            f = open("C:\\Users\\aaron\\Desktop\\output.txt", "a")
            f.write(pprint.pformat(message))
            f.close()
    
        def __init__(self, applicationStore, launcher):
            '''Initialise action with *applicationStore*.'''
            super(BlenderAction, self).__init__()
    
            self.logger = logging.getLogger(
                __name__ + '.' + self.__class__.__name__
            )
    
            self.applicationStore = applicationStore
            self.launcher = launcher
    
            if self.identifier is None:
                raise ValueError('The action must be given an identifier.')
    
        def register(self, session):
            '''Register action.'''
            session.event_hub.subscribe(
                'topic=ftrack.action.discover',
                self.discover
            )
    
            session.event_hub.subscribe(
                'topic=ftrack.action.launch and data.actionIdentifier={0}'.format(
                    self.identifier
                ),
                self.launch
            )
    
            self.session = session
    
        def is_component(self, selection):
            if (
                len(selection) != 1 or
                selection[0]['entityType'] != 'Component'
            ):
                return False
    
            return True
            
        def discover(self, event):
            '''Return action based on *event*.'''
    
            launchArguments = []
    
            selection = event['data'].get('selection', [])
    
            if self.is_component(selection):
                component = self.session.get('Component', selection[0]['entityId'])
                
                if component is not None:
                    location = self.session.pick_location()
                    url = location.get_filesystem_path(component)
                    launchArguments.append(url)
                    
    
            items = []
            applications = self.applicationStore.applications
            applications = sorted(
                applications, key=lambda application: application['label']
            )
    
            for application in applications:
                applicationIdentifier = application['identifier']
                label = application['label']
                items.append({
                    'actionIdentifier': self.identifier,
                    'label': label,
                    'icon': 'http://icons.iconarchive.com/icons/dakirby309/simply-styled/256/Blender-icon.png',
                    'applicationIdentifier': applicationIdentifier,
                    'launchArguments': ['c:\\Users\\aaron\\Desktop\\lookdev_addon.blend'] #launchArguments
                })
    
            return {
                'items': items
            }
    
        def launch(self, event):
            '''Callback method for Blender action.'''
            applicationIdentifier = (
                event['data']['applicationIdentifier']
            )
    
            context = event['data'].copy()
    
            return self.launcher.launch(
                applicationIdentifier, context
            )
    
    class ApplicationLauncher(ftrack_connect.application.ApplicationLauncher):
        '''Custom launcher to modify environment before launch.'''
    
        def __debug(self, message):
            f = open("C:\\Users\\aaron\\Desktop\\output.txt", "a")
            f.write(pprint.pformat(message))
            f.close()
        
        def _getApplicationLaunchCommand(self, application, context=None):
            command = ftrack_connect.application.ApplicationLauncher._getApplicationLaunchCommand(self, application, context)
            self.__debug(command)
            return command
    
    def register(session, **kw):
        '''Register action in Connect.'''
    
        # Validate that session is an instance of ftrack_api.Session. If not, assume
        # that register is being called from an old or incompatible API and return
        # without doing anything.
        if not isinstance(session, ftrack_api.Session):
            return
    
        applicationStore = ApplicationStore()
    
        launcher = ApplicationLauncher(
            applicationStore
        )
    
        action = BlenderAction(applicationStore, launcher)
        action.register(session)

    Here's the full hook. To be honest, it's not too much different from the Houdini example in the docs at the moment, which is why I'm not sure what's going on. Let me know if something sticks out.

  3. @Lorenzo Angeli When I checked the log file there was no such line. So, I did some testing.

    First, I removed both my Blender plugin and the Perforce plugin and tried to run Photoshop. That time, I did see a "launch" log line.

    When I enabled only the Perforce plugin and tried to run Photoshop, I got the same results I did the first time: significantly smaller log file with no "launch" log.

    Enabling Blender only, I was able to see a launch log line but it doesn't appear to be attaching the launchArguments to the command if I'm reading it right. I hard-coded a path to an existing file to test.

    2020-06-20 11:55:34,707 - ftrack_connect.ui.widget.actions.Actions - DEBUG - Before action launched: {'selection': [], 'applicationIdentifier': 'blender_2.82', 'label': 'Blender 2.82', 'actionIdentifier': 'blender-launch-action', 'launchArguments': ['c:\\Users\\aaron\\Desktop\\lookdev_addon.blend'], 'icon': 'http://icons.iconarchive.com/icons/dakirby309/simply-styled/256/Blender-icon.png'}
    2020-06-20 11:55:34,786 - ftrack_connect.application.ApplicationLauncher - DEBUG - Launching ['C:\\Program Files\\Blender Foundation\\Blender 2.82\\blender.exe'] with options {'close_fds': True, 'cwd': 'C:\\Program Files\\Blender Foundation\\Blender 2.82', 'env': {#environment variables here#}
    2020-06-20 11:55:34,796 - ftrack_connect.application.ApplicationLauncher - DEBUG - blender_2.82 application started. (pid=14384)
    2020-06-20 11:55:34,798 - ftrack_connect.ui.widget.action_item.ActionItem - DEBUG - Launched action with result: [{'message': 'Blender 2.82 application started.', 'success': True}]
    2020-06-20 11:55:34,826 - ftrack_connect.ui.widget.actions.Actions - DEBUG - Action launched: {'selection': [], 'applicationIdentifier': 'blender_2.82', 'label': 'Blender 2.82', 'actionIdentifier': 'blender-launch-action', 'launchArguments': ['c:\\Users\\aaron\\Desktop\\lookdev_addon.blend'], 'icon': 'http://icons.iconarchive.com/icons/dakirby309/simply-styled/256/Blender-icon.png'}

     

  4. Thanks Lorenzo, that works great.

    All of a sudden though, ftrack doesn't want to launch Blender with the edited launchArguments parameter. I had it working at one point a couple of weeks ago, and left it alone to take another look at my Perforce issues. Now that I'm revisiting this, it's giving me grief.

    The expected launchArguments are in the event['data'] object - this is what I get if I print out event['data'] just before passing it to launcher.launch() (file path changed to protect client):

    {u'actionIdentifier': u'blender-launch-action',
     u'applicationIdentifier': u'blender_2.82',
     u'icon': u'http://icons.iconarchive.com/icons/dakirby309/simply-styled/256/Blender-icon.png',
     u'label': u'Blender 2.82',
     u'launchArguments': [u'c:\\Users\\aaron\\Perforce\\path\\to\\file.blend'],
     u'selection': [{u'entityId': u'cce25bb7-b9ee-41a5-8278-db5c47d21940',
                     u'entityType': u'Component'}]}

    And here are my discover() and launch() functions for reference:

    def discover(self, event):
      '''Return action based on *event*.'''
    
      launchArguments = []
    
      selection = event['data'].get('selection', [])
    
      if self.is_component(selection): # custom helper function
      	component = self.session.get('Component', selection[0]['entityId'])
                
        if component is not None:
        	location = self.session.pick_location()
            url = location.get_filesystem_path(component)
            launchArguments.append(url)
                    
    
        items = []
        applications = self.applicationStore.applications
        applications = sorted(
          	applications, key=lambda application: application['label']
        )
    
        for application in applications:
            applicationIdentifier = application['identifier']
            label = application['label']
            items.append({
                'actionIdentifier': self.identifier,
                'label': label,
                'icon': 'http://icons.iconarchive.com/icons/dakirby309/simply-styled/256/Blender-icon.png',
                'applicationIdentifier': applicationIdentifier,
                'launchArguments': launchArguments
            })
    
    	return {
            'items': items
        }
    
    def launch(self, event):
        '''Callback method for Blender action.'''
        applicationIdentifier = (
            event['data']['applicationIdentifier']
        )
    
        context = event['data'].copy()
    
        self.__debug(context) # custom debug helper function
    
        return self.launcher.launch(
            applicationIdentifier, context
        )

    Nothing unusual is showing up in the main ftrack log file, but I don't know if it would.

  5. Ok, so here's a little update!

    If I run the action against the component, I can pull the file path with:

    selection = event['data'].get('selection', [])
    component = self.session.get('Component', selection[0]['entityId'])
    if component is not None:
      # this is an internal function that prints to a file on my desktop for quick debugging
      # returns 'u'https://ftrack-us-east-1.s3-accelerate.amazonaws.com/68d68ada-9f98-11ea-96a3-42010af0000d/storage/5/5/0/f/f586-a218-11ea-8422-72ed585b6b9d?Signature=iUglFLXGsXDm4pTY7RvA5gFxn%2BQ%3D&Expires=1590812357&AWSAccessKeyId=AKIAYKW36AUCL5BMAVWP'
      self.__debug(component['component_locations'][0]['url']['value'])

    Is there a better way to do this or am I on the right track?

  6. I built a little Blender launcher action for Connect so I can integrate ftrack with my current studio setup. I have a basic launcher working well, and can open Blender both from Connect and the ftrack interface.

    How do I go a step further and tell it to open the component file associated with an asset? I've found some documentation pointing me in the right direction, but can't seem to make it to the finish line. Any pointers would be appreciated!

    I assume I should be grabbing the file location from the asset and pushing it through either the event data's "command" or "options" variables (http://ftrack-connect.rtd.ftrack.com/en/stable/developing/hooks/application_launch.html#developing-hooks-application-launch). Because opening a blend file from the command line isn't a keyword argument (ie, "blender my_blend_file.blend") it should be under the command variable, but I can't figure out how to get it to work. Here is my launch function:

    def launch(self, event):
            '''Callback method for Blender action.'''
            applicationIdentifier = (
                event['data']['applicationIdentifier']
            )
    
            self.logger.debug(
                pprint(event['data'])
            )
    
            context = event['data'].copy()
            
            # Tried opening a test file, but this crashes the action. Removing it opens default Blender file.
            #context['data']['command'].append('C:\\Users\\aaron\\Desktop\\test.blend')
    
            return self.launcher.launch(
                applicationIdentifier, context
            )

    I've spent some time in the Maya action source code, but found little helpful for this particular problem. https://bitbucket.org/ftrack/ftrack-connect-maya/src/394b8d7a065bb67469386391caa9d883165e926a/resource/hook/ftrack_connect_maya_hook.py?at=master#ftrack_connect_maya_hook.py-74,89,117,126,131,134,137:138

×
×
  • Create New...