In adding operations to modelbuilder v6, we want to improve on the drop-down list in v5. One thing we want to do is present operations that can be applied to the currently selected components. However, this seemingly simple task is not well-defined upon closer inspection. Some complicating factors are:
- Operations specify components that are acceptable by providing a list of (resource type, filter) string tuples. The filter string is opaque to resource and operation managers; they ask individual resources to provide a C++ lambda that uses the string to determine whether a component owned by that resource is acceptable. With many operations, each of which may have many acceptable tuples, and many components in a selection, this can be expensive, especially since the filter string may need to be parsed before it can be used.
- While it is fast to discriminate on the subclass of smtk::resource::Component (or equivalently, its typeinfo), we want to accommodate filtering on:
-
model entity types. Model vertices, edges, faces, volumes, etc. are all represented by instances of a single class (
smtk::model::Entity
) but we want to discriminate among them. - role. In the future we want to be able to assign any number of arbitrary string tags to components which specify their role in the model. Operations should be able to specify their inputs in terms of these roles. For example, model edges may represent rivers, roads, train tracks, and bike paths in a simulation; an operator may only work on rivers.
- expressions. Even more complex filters are possible, either because attributes present on input components are used as discriminators or because the discriminator is a function of multiple components (e.g., an operator that cannot be applied to model volumes with different material attributes).
-
model entity types. Model vertices, edges, faces, volumes, etc. are all represented by instances of a single class (
- Another desire is to behave differently when an operator may be immediately applied because it does not accept further input (beyond the current selection), when an operator requires further input, or when an operator accepts further input but provides acceptable default values and thus may be applied immediately.
There are also things our current code does that may not be what we want:
- Selections may be large and our current API is
which could be very expensive. The reason this is expensive is that each time it is called, this method causes resources to re-parse the filter/query strings (there may be several) that each operator provides.bool smtk::operation::Manager::availableOperations(smtk::resource::ComponentPtr component)
- We currently ignore restrictions each operator places on the number of components allowed. This would be a good way to terminate early and provide speedups, although it may also be constraining to users if it is difficult for them to select just the entities they are interested in.
- We currently check all items of every definition in each operator’s attribute collection and probably don’t want to (because how would we assign components in the selection when there are multiple items?).
- We currently don’t check associations allowed by any definition in each operator’s attribute collection, and should probably check only associations on the operator’s parameters() attribute definition.
How should we close the gap between what we have implemented and what we believe will be both effective for users and tractable for computers?