Skip to main content

Download the entire extension

Introduction

In this guide, we want to show you how to customise the publisher to export multiple components.

There are multiple approaches in order to successfully extend the publisher to export multiple components, all them are based on modifying the publisher tool-config, for example:

  • Creating a group for each component, with a collector and exporter so you don't have to modify the UI.
  • Having just one collector and multiple exporter plugins inside the same group. (You shouldn't be in need of modifying the UI, but you will have to change the store_component plugin to enable the options/component key of the group to support multiple components)
  • Removing the groups and just having a plain collector plugin and plain export plugins (see the common validator plugin "exported_paths_validator" or the "publish_to_ftrack" plugin)

In order to make this guide as simpler and clear as possible we are going to guide you through first approach.

  • We are going to customise the publisher without touching the UI code. We are going to modify the tool config to be able to publish an extra abc component among all the default ones.
    • If you like to export more components a part from the ABC like FBX, you just need to reproduce the same steps for each new component.

Alt text

Preparation

  • Download Maya plugin with Connect PM

  • Go to the downloaded maya plugin folder and copy the extensions and launch folders to your desired custom location to generate a structured folder (All extensions can be in a plain folder or structured in your desired way.)

  • Point FTRACK_CONNECT_EXTENSIONS_PATH to the launch folder:

    export FTRACK_CONNECT_EXTENSIONS_PATH='<your_custom_extensions_path>/launch'
  • Modify the launch-config to override the extensions folder: You have 2 options here (First one is the recommended one as you will still have access to the default plugins, dialogs, etc provided by ftrack and you will be able to use them):

    • Maintain current extensions and just add/override the desired ones (First one takes priority)
    type: launch_config
    name: framework-photoshop
    extensions_path:
    - <your_custom_extensions_path>/extensions
    - extensions/common
    - extensions/photoshop
    • Totally override the extensions and don't have access to the default ones anymore.
    type: launch_config
    name: framework-photoshop
    extensions_path:
    - <your_custom_extensions_path>/extensions
  • We do a first level merging on the yaml files, so you don't need to keep all the sections of the original file, you just need to keep the modified ones + type and name to be able to identify it as an extension.

  • PLEASE MAKE SURE YOU HAVE THE MAYA ABC PLUGIN ACTIVATED TO MAKE THIS EXAMPLE WORK.

Implementation

Let start by leaving just the needed referenced files for this example.

  • Remove the entire common folder
  • Remove all files from the maya folder except:
    • maya/plugins/maya_camera_collector.py
    • maya/plugins/maya_scene_exporter.py
    • maya/plugins/maya_camera_exists_validator.py
    • maya/widgets/maya_camera_selector.py
    • maya/tool-configs/maya-scene-publisher.yaml

Tool-config

  • Modify the maya/tool-configs/maya-scene-publisher.yaml
  • Duplicate the snapshot group and modify the options/component to abc.
  • Add the optional key and set it to true if you want the user to decide if to export the component or not.
  • Add the enabled and set it to false if you want the component to appear unselected by default.
  • Modify the collector plugin to use your custom plugin fex: maya_chr_collector
  • Modify the ui to use your own representation widget for your collector plugin (UI is optional, if you don't setup a UI, the plugin will not be represented on the publisher dialog)
  • Set the default desired options. For example:
    • can_override = false # means that the automatically collected object by the plugin can't be overriden.
    • expression = "_chr" # means that the plugin will collect the geometry that ends with _chr .
    • collected_chr_object # In the example we are not setting any hardcoded collected_object but the plugin once executed will collect the _chr object and set it as collected object. If desired by the TD it can be hardcoded so the plugin always export the same thing.
  • Modify the validator plugin to point to our custom maya_object_exists_validator
    • You can add as many validators as you like. You could also remove them all.
  • Modify the exporter plugin to point to the maya_abc_exporter plugin and to the maya_abc_options_selector.
    • If you want, you could add the options section and hardcode the default options, so you don't need the user to select the options.

Collector plugin

  • For reference and in order to have some sort of template, I would suggest to start from the most similar default plugin which in this case is the maya_camera_collector plugin.
  • Rename the maya_camera_collector.py file to maya_chr_collector.py
  • Edit the file and rename the class to MayaChrCollectorPlugin
  • Tename the name variable to maya_chr_collector (This is the most important part, this is the name picked by the tool-config)
  • The ui_hook is the method executed by the ui widget so it can fetch the data
    • Modify this to send the right object to the UI.
    • Pick the expression and collected_chr_object from the payload
    • Check if collected_chr_object has been hardcoded in the tool-config and return that name if so.
    • Otherwise, return the matching object from the maya scene (return None if no matching object)
  • The run method is the main method executed by the plugin.
    • Pick the chr object from the options / collected_chr_object passed by the UI. (We will go into more details on the ui section)
    • Pick the component name defined on the tool config group from the self.options (self.options contains the specific plugin options + the group options)
    • Fill the store with the collected_chr_object to pass it to the next plugins.

Collector plugin UI

  • Inside the widgets folder, pick the most similar one in this case maya_camera_selector.py and rename it to maya_chr_selector.py
  • Rename the name of the class to MayaCHRSelectorWidget (remember to replace all super calls with the new name)
  • Rename the name variable to maya_chr_selector
  • Do all desired changes, we will only write down the most relevant ones for this example.
  • In the build_ui section, modify the camera_cb to instead of beign a combo box be a line edit
  • From the self.plugin_config (This gives us acces to the specific plugin definition section of the tool config) pick the can_override option and if false, set the QLineEdit setReadOnly property based on the can override.
  • Rename camera_cb to chr_le in all matching sections.
  • On the post_build_ui: Rename the currentTextChanged signal to textChanged and the callback to on_chr_changed as well as the method.
  • pre_build_ui, build_ui and post_build_ui methods should be kept as are overrides of the base plugin.
    • Populate and ui_hook_callback methods should also be kept if you need to interact with the plugin.
  • Modify the set_plugin_option on the to setup the collected_chr_object option.
    • This will edit the tool_config and add the chr_name in the collected_chr_object option.
  • Modify populate method to call the query_chr_object instead of the query_cameras.
    • Fill the payload dictionary to have expression and collected_chr_object names on it
    • Pick the options from the plugin_config.
payload = {
'expression': self.plugin_config['options'].get('expression', '_char'),
'collected_chr_object': self.plugin_config['options'].get('collected_chr_object')
}
  • Rename the query_cameras method to query_chr_object and modify it accordingly:
    • If ui_hook_result is different than None, then set the text of the line edit to the one returned by the result

Validator

  • Back on the plugins folder, pick the maya_camera_exists_validator, and rename it to maya_object_exists_validator
  • Same as previous plugins, rename the class, the name variable and do the modifications on the run method.
  • In the run method we want to pick the component name from the group of the tool-config that the plugin is currently executed from.
  • Then we pick the collected_chr_object collected on the collector plugin
  • We check if the collected_chr_object exists in the maya scene
    • We rise a validation error in case it doesn't exists.
    • Note that the validation error can call an autofix method to attempt to fix the error. We are not doing that in this example but please check the maya_scene_saved_validator.py line 67 and 74 to see an example.
  • Finally, we set a valid object key to the store to know that the collected object is valid in case we want to check that in next executed plugins.

Exporter

To create the exporter plugin we will do the same as in the collector section, we will first modify the plugin and then the UI.

  • We can pick the maya_scene_exporter as reference and rename it to maya_abc_exporter.
  • For this example we are just going to allow overriding the abc framerange option from the UI.
  • Pick the component_name that we are working on
  • Generate a temporal path with the abc extension fomat.
  • Get the collected object from the store
  • Get the start_frame and end_frame from the options (They will be set by the UI)
  • Call the ABCExport command to export the collected_chr_object to the exported_path
  • Save the exported_path into the store to be picked by next plugins (This is important for the publish_to_ftrack plugin)

Exporter plugin UI

  • On the widgets folder we can duplicate the maya_chr_selector.py rename it and use that one as a template.
  • Rename the class and the variable name
  • On the build_ui create 2 line edits and rename them to start frame and end frame
    • Pick the default start and end frame from the options section of the specific plugin tool-config in case they are set.
    • (optional)Create a new layout to set up labels on the line edits to better identify start frame and end frame sections.
  • Rename the on_chr_changed to _on_start_frame_changed and create a new one with _on_end_frame_changed
  • Remove the populate, query_chr_object and ui_hook_callback methods as we don't need the plugin to process anything for this UI

Download the entire extension