Preset Browser Paths

The ./Preset Browser viewport (sometimes shortened to PBView on the [ forums]) is a thumbnail-based file browser for locating ‘’modo’’-related content from a series of ‘’base paths’’, which can then be loaded via drag and drop or by double-clicking on the file. Originally intended for presets, it also supports images and can be extended to other file types through plug-ins.

Base Paths

Preset Browsers are built on two underlying user interface elements: The ‘’DirBrowser’’, and the DirThumbBrowser (which in turn is built on a ‘’ThumbBrowser’’, and sometimes a tree pane). These are not themselves currently exposed to plug-ins for custom interfaces, but it can help to know how the browser is built when defining a custom Preset Browser viewport.

The DirBrowser pane is on the left of the browser. It shows a specific set of directories from the file system known as ‘’’base paths’’. The lists of base paths can be changed at any time by the user by clicking the “X” to delete one, or the “(new path)” entry to add a new one. You can make an entire drive a base path if you like, although that isn’t usually done. Instead, specific sets of directories containing ‘’modo’’-specific content are usually set so that you can easily jump to the relevant directories without having to wade through all the others. It’s also important to note that the base paths are associated with the DirBrowser, and it is that which manages those paths in the config.

When a Preset Browser viewport is created, it tells the DirBrowser to initially use the global presetChoice set of base paths. At present there is no way to change the set of base paths from the UI, as it was intended to be an advanced feature used by developers. It can, however, be changed by modifying the config file directly.

Prior to Modo 12, each base path represented a single real or synthetic path. Modo 12 introduced ‘’merged base paths’’, and upgraded base paths into ‘’base path sets’’. To the user this looks just like a normal base path, but it actually contains one or more real path locations on disk, which are shown to the user as a single merged hierarchy. This has some advantages which will be described later.

Merged Base Paths

Merged base paths allow a multiple related paths to be viewed as a single hierarchy in the Preset Browser. A common example is the “asset” directory in the default Preset Browser. The issue is that we have three standard locations for assets:

  • documents:Modo assets, where new assets are created

  • asset:, where the downloaded and installed content exists

  • kit_modo_assets:, a kit included with modo that contains some default assets

User Interface

To the end user it looks like there are only the normal set of paths they’ve always seen, just like in older versions of Modo before 12. However, after flipping the ‘’’Show Original File Structure for Merged Paths’’’ switch in the Application section of the preferences, a set of attribute expansion widgets will appear next to each of the root entries in the PBView’s left hand DirBrowser. Unfolding one of these will show the ‘’component paths’’ that make up the merged ‘’base path set’’. Component paths can be unfolded and examined individually, but the merged set is what the user will most often interact with.

New component paths can be added to a set by clicking the ‘’(add path)’’ entry, and they can be removed by clicking in the X column. Empty sets are removed automatically once all their component paths are removed. Sets can be renamed, with the name being stored in the config along with their component paths.

The order of the component paths is important. While the directory contents are merged, only one file with a given filename will be shown in the browser, even if it shows up in multiple component paths. If the file comes from a more topmost component path, it will override the lower-level files, and will be always be shown. The other versions of that file cannot be accessed at this time. The component paths in a path set can be reordered with drag and drop.

The topmost component path also has a special designation as the ‘’’user path’’’. When drag and dropping files into the browser, this is the path where files will be moved to or created in, even if the folder doesn’t currently exist (it will be created as part of the drop). This ensures the user-created content is always placed in a consistent location, and is never modified by updates to modo, and always take precedent over anything that modo comes with natively.

Under the Hood

This is somewhat technical and not relevant if you just want to add some merged paths to your Preset Browser configs.

The dir cache continues to exist as it always have, being made up of ILxDirCacheEntry objects. The main difference is that the UI only shows those raw objects as component paths. Merged paths are represented as ILxMergedDirCacheEntry objects that also have the ILxDirCacheEntry interface, and are what the user will see most of the time in the browser, unless they explicitly go into an component path.

Merged entries have their own path format, always starting with ‘’’#basePathIdent(setName):’’’. The octothorp (#) is how we identify that this as a merged path. The basePathIdent is the identifier used to associate this set of paths with this preset browser. The setName is the name of this specific base path set. Directories inside the set are accessed with a normal forward slashes as path separators.

Merged entries expose both an ILxDirCacheEntry interface and an ILxMergedDirCacheEntry interface . The former provides all the normal information about the entry. The merged interface provides access to the entries at this location. For directories, this is the paths that were used to create the merged file and directory list. For files, this is the list of all the files with the same name from all of the directories that were merged here.

Merged entries also return a user path. The user path is important, as it is the location that files are written to. This is available for both files and directories, although the actual location may not yet exist on disk. An SDK utility makes it easy to build a complete path hierarchy when adding files to the user dir. There are also utility functions to create and split any dir cache path string.

Double-clicking a preset will load it as normal, and will use the topmost local path, not the merged path (ie: it won’t start with “#”). Context menus are also presented with the original path, and operate normally as well. Drag and drop out of the browser uses the local path, but also optionally provides the merged path via an alternate drag source. Similarly, the destination always reports the user path, but the merged entries at this location are also available. Grid mode and manual order destinations always provide the merged path, as that is where this information is stored, but the FileSysDest and MergedFileSysDest are also available when the local path or other merged path in formation is desired.

User markup is stored for merged paths in ‘’user:_mergedPaths_/basePathIdent/setName’’. This only contains the grid positions and manual ordering for the merged directory, as those are unique to the merged entry. Individual file markup and metadata are pulled from the original files and directories.

Config Format

Config Examples

Examples of some common base path sets can be found in ‘’resrc/EmbeddedBrowsers.cfg’’. Some of the Preset Browser viewports referenced there are embedded into ./Form View for use by tools, and use other properties like Hash that aren’t directly applicable to more general Preset Browsers.

Before Modo 12

Merged base paths were implemented in Modo 12. Before that, a single path was each base path set, via ClientPath entries in the ‘’DirBrowser” part of a config file . Anything targeting Modo 12 or later should use merged base paths, and older config entries will be promoted to merged sets. You then edit a Preset Browser’s config state to use that set of base paths by changing its OverrideDefaultBasePaths atom (see below) to match those ClientPath entries.

The list of base paths are stored in the DirBrowser portion of a config file. This includes both base paths and information specific to particular Preset Browser instances.

  <atom type="DirBrowser">
    <hash type="ClientPath" key="presetChoiceBasePaths@asset:">1</hash>
    <hash type="StateCurrentPath" key="presetChoiceHash">asset:</hash>
    <hash type="StatePathExpand" key="presetChoiceHash@asset:">1</hash>

The word “state” is used in those names to indicate that they are state that changes simply by interacting with the browser, in these cases by clicking on a different directory or by collapsing/expanding a parent directory. These are specific to a viewport instance, and use a hash defined by that Preset Browser viewport.

The word “client” in ClientPath is used as a synonym for “base path set”, in that it indicates the intended use of this set of paths. Multiple views may share the same set of paths.

  • ClientPath is a specific path. The key is in the form of ‘’’’’basePathSet’’’@’’’path’’’’’, where basePathSet is the name you would use in the OverrideDefaultBasePaths portion of a Preset Browser’s config entry, and path is the path on disk. The path can be an alias or an absolute path on the file system. The number 1 indicates that this entry will be shown in the browser, while a 0 indicates that it has been “deleted”. This exists to work around the fact that you can only delete entries user configs; we simply mark it as deleted so that we know to ignore it on load. There can be as many ClientPath entries as you like for a given base path set.

  • StateCurrentPath is the current path for a given base path set. The key is the Hash atom from a Preset Browser viewport, while the value is the current path. This can be used to point the browser to a specific path when it is instantiated, and changes when the user changes the current directory through the UI. There is only one of these per base path set.

  • StatePathExpand indicates if a given in a given Preset Browser is expanded or collapsed in the DirBrowser tree. If the value is ‘’1’’, the path is expanded, while 0 is used to collapse it. The key format is the same as for ‘’ClientPath’’. There can be one of these for each ClientPath entry.

The config format for merged base paths is similar to the old ClientPath setup, but it had to change to accommodate base path sets. If ClientPath entries are found in the config, they will be promoted to BaseParthEntrys.

For example, here are three paths added to the presetChoice base path identifier, inside the “asset” set. Each path has an ordinal that determines its sort order, with lower ordinals going first, and the lowest ordinal being the user path.

    <hash type="BasePathEntry" key="presetChoice(asset)=documents:Modo Content/Assets">64</hash>
    <hash type="BasePathEntry" key="presetChoice(asset)=asset:">128</hash>
    <hash type="BasePathEntry" key="presetChoice(asset)=kit_Modo_Content:Assets">192</hash>

Base path sets can also have a username. If none is provided, the name of the topmost path in the set is used instead.

    <hash type="BasePathUsername" key="presetChoice(asset)@en_US">Assets</hash>

Expansion and current path are similar to how they were set before Modo 12 in the past, but now use full paths with the new merged format of ‘’#basePathIdent(asset):’’. Note that you do not use the # and : when defining a set or its name above; it is only needed below because it is part of a path.

    <hash type="StateCurrentPath" key="presetChoice">#presetChoice(asset):</hash>
    <hash type="StatePathExpand" key="presetChoice@#presetChoice(asset):">1</hash>

Adding Paths for Current and Legacy Modo in the Same Kit

In the current modo, you’ll want to use ‘’BasePathEntry’’s, but in legacy modo you’ll want to use ‘’ClientPath’’s. The trick is that modo 12 will load both of those paths. To avoid this, you’ll want to add SkipClientPath entries for each ClientPath entry. This will be ignored pre-12, but 12 will use them to skip the legacy entries and use only the BasePathEntry keys.

First we add our ‘’BasePathEntry’’s for modo 12:

    <hash type="BasePathEntry" key="presetChoice(asset)=documents:Modo Content/Assets">64</hash>
    <hash type="BasePathEntry" key="presetChoice(asset)=asset:">128</hash>
    <hash type="BasePathEntry" key="presetChoice(asset)=kit_Modo_Content:Assets">192</hash>

Now we add our legacy ‘’ClientPath’’s:

    <hash type="ClientPath" key="presetChoice@C:\MyPath">1</hash>

And now we tell modo 12 not to skip the ClientPath with ‘’SkipClientPath’’:

    <hash type="SkipClientPath" key="presetChoice@C:\MyPath">1</hash>

Preset Browsers and Base Path Sets

The Preset Browser references a specific set of base paths as part of its viewport state in the config file..

 <atom type="Frame">
    <hash type="presetbrowserview" key="base.Meshes" val="1">
      <atom type="Hash">MeshesViewState</atom>
      <atom type="OverrideDefaultBasePaths">MeshesClientBasePaths</atom>
      <atom type="Identifier">MeshesIdentifier</atom>
      <atom type="FilterBy">meshLayer</atom>
      <atom type="MinHeader">1</atom>
      <atom type="ViewportTitle">Mesh Preset Browser</atom>
  • Hash is a unique hash that is used to identify the DirBrowser state for this Preset Browser, and is usually unique for a given Preset Browser instance. This is used to store things like the current directory for a given Preset Browser, and which directories are expanded or collapsed in that view’s DirBrowser pane.

  • OverrideDefaultBasePaths is the name of a ‘’base path set’’, as described below, and determines which base paths show up in the DirBrowser pane. If empty or omitted (such as when creating a new Preset Browser viewport from the UI), the default “‘presetChoice’’ set is used.

  • Identifier is a selection sub-type that clients can read for special purposes. An example is the Polygon Bevel tool, which uses the hash to define a selection sub-type that will remain available even if a preset is selected in another general preset browser.

  • FilterBy allows the browser to be filtered to only show presets that match a specific server. In modo 601 and earlier, this was the GUID alias of the destination interface the preset server expected for drag and drop, but this is likely to change in the future to just the name of the preset server that recognized the file. This can be changed from the viewport’s options in the UI, although in practice a directory usually only contains one kind of preset, so this usually isn’t needed.

When a Preset Browser is in Group mode, the groups are listed alphabetically. This can be overridden by adding SortAsGroupAt entries. Note that these are in the DirThumbBrowser atom, not the DirBrowser atom, as they’re used at a higher level than the dir browser itself. The path affected is the hash, followed by an ordinal and an enable state. Lower ordinals sort first. When the enable state is 1, this is used for sorting; if 0, only alpha sorting is used for this path. Child paths will use the same sorting if found, so you don’t have to specify it for every path in the hierarchy.

For example, this is used in the Add Operation Preset Browser in the Mesh Ops view to make sure that the Mesh Op Items before all other items.

    <atom type="DirThumbBrowser">
        <hash type="SortAsGroupAt" key="#DeformerPBPath(meshOpItems):">64 1</hash>

More Information

  • ./Config System

  • ./Preset Browser Viewport