![]() |
ufe
1.0
Universal Front End is a DCC-agnostic component that will allow a DCC to browse and edit data in multiple data models
|
The design goal of the UFE project is to develop an independent component that allows a Digital Content Creation (DCC) application to operate on objects from different plugin run-times.
An example is to allow Maya to view and edit objects not just from its native DG (Dependency Graph), but also from plugin run-times such as Bifrost and USD.
A UFE-enabled DCC creates UFE interface objects on UFE scene items, then calls methods on the interface object.
Maya API programmers will see a clear analog with MFn function sets, which are interfaces on underlying objects.
UFE scene items are represented as a path through the scene graph, and the path is component of one or more path segments. Each path segment corresponds to a single run-time. Each path segment is composed of one or more path components.
UFE interfaces are bound to UFE scene items, one scene item at a time. The expected usage of a UFE interface object is to create one, bind it to a scene item, then operate on the scene item through the interface until the operation is complete. The UFE interface can then be discarded, or bound onto another scene item. This avoids the memory-consuming "one proxy object per scene object" approach.
A scene item may optionally represent a property associated with a given scene object. A property represents data associated with a single node or object. In different run-times, it is variously known as an attribute, a component, or an underworld path, but is always associated with a single node or object. At time of writing (24-Apr-2018), UFE only supports querying the existence of such data on a scene item, using Ufe::SceneItem::isProperty() .
The UFE standalone component defines interfaces that DCC plugin run-times must implement. When the DCC plugin run-time loads into the DCC, it registers its implementation of the UFE interfaces with the UFE run-time manager. From that point on, the UFE run-time manager will know how to create interface objects for that run-time.
The UFE component defines abstract interfaces. These define semantics that concrete UFE derived class concrete interfaces must implement.
The concrete implementation of one or more interfaces for a given run-time can be either built into the DCC, or provided by a plugin to that DCC. Providing UFE support through a DCC plugin has several advantages, all related to the fact that the plugin is a separate software component:
The sequence of steps, and the software components that participate in implementing this scheme, are the following. Let us call the plugin that provides UFE support to the DCC the UFE plugin. Since this is the most flexible way of providing UFE support in a DCC, we will base our description on this approach, though DCC builtin code can follow exactly the same procedure.
The following component diagram illustrates the responsibilities and dependencies of the different objects.
The following sequence diagram illustrates the flow of control between the different components and objects.
UFE supports the Observer Pattern to allow Views in the Model-view-controller Pattern to update on changes.
Observable objects in UFE (Subjects, in Observer Pattern terminology) include an Ufe::ObservableSelection, derived from the Ufe::Selection base class, to be notified of selection changes, as well as scene items that support the Ufe::Transform3d interface, to be notified of 3D transform changes on those scene objects. To receive notifications, clients must create an Ufe::Observer object, and add it to the Subject to be observed.
It is the intention of UFE to encapsulate native run-time notifications so that UFE clients do not have to use the native run-time API to receive notifications, and can rely on UFE alone.
At time of writing (13-Mar-2018), UFE does not support notification grouping, so that multiple fine-grained notifications can be delivered to observers in a single transaction. However, this support is desired and intended to be present in a future version of UFE.
The Ufe::Selection class provides the following services and performance characteristics. Assuming a scene item with a path of m components, and a selection list that already has n scene items:
Internally, each selection maintains a Trie of scene items to accelerate lookup.
UFE clients can create any number of Ufe::Selection objects for their needs. UFE supports the concept of a Ufe::GlobalSelection singleton, which contains an observable selection. This is intended to match DCCs which use a single, global selection as the workflow mechanism to determine what a user will view or edit. The DCC can set the Ufe::GlobalSelection observable selection using Ufe::GlobalSelection::initializeInstance() .
UFE provides support for DCC services like undo / redo. In all UFE interfaces that modify objects, each operation has two calls, one with undo capability, and one without. Providing undo capability typically involves code complexity, and using undo capability incurs run-time cost in processing and memory. Therefore, non-interactive use of an interface should use calls without undo capability.
The UFE interface calls that provide undo capability do so by supporting the Command Pattern, to allow the host application to execute and unexecute the operation.
UFE uses the familiar semantic versioning scheme. This implies binary backwardly compatible minor versions, so that plugins and clients will be able to pickup a new UFE minor version without needing to recompile.
UFE will attempt to have mostly source code backwardly compatible major versions, so that only minor changes to existing code are necessary when updating to a new major version.
The UFE API is namespaced using the major version number. For ease of use, UFE uses a C++ using namespace declaration to present a familiar un-versioned Ufe namespace to client code, while keeping the actual symbols in the shared library versioned.
UFE provides the Ufe::VersionInfo class to retrieve versioning information. It is possible to obtain major, minor, and patch versions, as well as build number, commit SHA, branch name, and build date, both from C++ and from Python.