A simple and quick guide on how to write a new descriptive phrase generation
- This post is WIP.
Preface
- Descriptive phrase trees may be flat or deeply nested. They are flexible and may be configured to present the same resources and components in many different ways, while accommodating changes to those resources and components in response to editing operations. In order to deal with the complexity of descriptive phrase generation, the duties are split across several classes which are introduced below.
Key components
Phrase models
- Normally it’s needed to implement your own subclass.
- You can think it as the model in MVC pattern. It’s responsible for determining which descriptive
phrases belong at the root of the tree. It allows you to watch for events that may change
the tree and determine how to notify user interfaces of those changes in terms of deleted,
added, re-ordered and modified phrases.- Functions recommended to override:
- root(): You can view it as the root node of the tree
- create(): Setup the relationship between subphrase generator and the phrase model
- handleResourceEvent()
- handleCreated(), handleModified(), handleExpunged(), etc
- Existing implementation:
- ComponentPhraseModel
- RGGPhraseModel
- SelectionPhraseModel
- ResourcePhraseMode
Descriptive phrases
- Normally it’s discouraged to implement your own subclass.
- It’s responsible for storing hierarchy(parent and children) and optionally, a reference to a subphrase generator that instructs the phrase model on how to populate the hierarchy on demand. In most cases, the subphrase generator is only stored in the root descriptive phrase. It also owns a reference to another class responsible for the phrase’s content(Ex. title, subtitle). See details about phrase content below.
Phrase Content
- Normally it’s optional to implement your own subclass.
- It owns a reference to a persistent object and determines what about that object should be presented.
- For example, in order to present a face F0 in the resource panel, let’s say we store the face in a PhraseContent PC0.
Now we want to add visibility control for face F0, we decorate PC0 with another PhraseContent PC1. If needed,
we can decorate n times and then we have PhraseContent PCn. PCn is stored in descriptive phrase DP0, and DP0 is shown in the resource panel.- Existing implementation:
- ResourcePhraseContent: describe a resource component
- PhraseListContent: describe a list of child phrase to user by model flags
- ComponentPhraseContent: describe a resource component
- VisibilityContent: add visibility control for resource component
- ObjectGroupPhraseContent: describe a set of persistent objects by smtk filter string
Subphrase generator
- Normally it’s needed to implement your own subclass.
- It’s responsible for creating and updating a list of child phrases when given a reference
to a potential parent phrase. Literally, it’s a generator.- Existing implementation:
- TwoLevelSubphraseGenerator
- EmptySubphraseGenerator
- ComponentsByTypeGenerator
Custom behaviors
- By default, CMB provides several expected behaviors such as view, selection, import/close resource, etc. You can see the complete list of supported behaviors in {smtk-src}/smtk/extension/paraview/appcomponents. Meanwhile, smtk provides mechanism to add custom behaviors. For instance, rgg session adds a new selection behavior that the selected components are the only visible objects in the render view.
Common questions
How to add a custom behavior?
- Custom behavior utilizes the ParaView plugin mechanism and smtk observer pattern. You need to do three things to add custom behavior:
- Add an auto start class to register custom behaviors with ParView framework if it does not exist in your session. Example file: pqSMTKAppComponentsAutoStart.h.
- Add desired custom behavior class. Example file: pqSMTKPipelineSelectionBehavior.h
- Add CMake logic. Example: {smtk-src}/smtk/extension/paraview/appcomponents/CMakeLists.txt