SHAPER
9.10.0
|
A SHAPER module consists of one or several plug-ins which provide implementation of Module features. To extend the application functionality, developers are able to add their own features into existent plugins. Also, it is possible to create a custom plugin, if necessary.
This document describes the basic principles of plugin/feature system and shows how to use the API for writing a feature or plugin. Currently, the API is available for C++ and Python languages. Plugin, written in C++ is a shared object (dll); For Python, it is regular python module, with *.py extension.
By default, all application's plugins are stored in the /plugins
folder. However, it is possible to change this path in preferences: "Preferences >> Module|Plugins >> Default Path".
The plugins directory have to contain plugins.xml
file, which declares plugins included in the module and describes their parameters, like this:
or, for python plugin:
First example declares FooPlugin, which is library (FooPlugin.dll
or FooPlugin.so
) with "plugin-Foo.xml" configuration file. The second - a Python module, PythonicPlugin.py
. All the declared libraries, scripts and configuration files should be placed in the same directory as the plugins.xml
. Note also, that library
and script
attributes should not contain any extensions (*.py, *.dll); However, the configuration
attribute doesn't have any pattern and just have to match name of the plugin configuration file.
The plugin configuration files contains description of features:
Here is example configuration for a feature for storing and editing a double value:
Now we will show how to implement a plugin with this feature using the C++ and Python APIs.
First of all, you should create/modify all configuration files (*.xml) in your plugin
directory, as shown in examples before. For plugin-Pythonic.xml
you may use the same content as in the plugin-Foo.xml
, just change the name of the feature, in example, to PythonDoubleCounter
. In this case you will get two features in one workbench and group, despite the fact that they are from different plugins.
Secondly, you should create a subclass of ModelAPI_Plugin. Constructor on the subclass should register itself in the application. In C++ it is:
And in Python:
Furthermore, your class must have implementation of the createFeature(...)
method, which should create corresponding feature object by the given id:
It is a bit more tricky for Python - you should pass the ownership of created object from Python to the application by calling the __disown__() method:
Now your plugin is able to create features, declared in its configuration file. However, to register the plugin properly, its constructor must be called on loading of the library (script), like this:
Please note, that some linux platforms required unique names for static variables.
For Python, note that this code should be in the module's namespace (has no leading spaces):
Plugin is created, lets pass over to the feature's implementation.
Like a plugin, feature has its own base class - ModelAPI_Feature.
Python:
And like a plugin implements a functionality to create 'feature' objects by string id, feature defines which type of data should be stored in model and how this data should be processed. The initAttributes(...)
method links feature's widget with data model:
Python:
As you may notice, this method defines that feature has a widget with "DoubleCounterData" id, which has Double type. Therefore, if your feature uses, in example, three widgets, the initAttributes()
method should 'init' three attributes.
Sometimes, it is not enough just to get data (ModelAPI_Data) from user input, and an internal logic (how to process the data) is required. The execute()
method gives ability to implement it. In our example, we will just print the data from the input to console:
Python:
Plugin allows creating of a specific property panel content and a custom widget. The panel content will be shown instead of controls container in the application property panel. The custom widget will be shown among other standard and custom widgets in the Property Panel.
To provide this SHAPER has a widget creator interface and a factory of the creators. Each plugin which creates panels or custom widgets should implement own creator and register it in this factory by some unique string-ID. This creator will be obtained by this name and create new controls. Steps to create the Qt property panel content are the following:
SamplePanelPlugin_Plugin is an example plugin to create a custom property panel.
Steps to create a custom widget are the following:
createFeature(...)
method initAttributes()
and execute()
methods If you writing a C++ plugin you should compile and link all sources in a dynamic link library (shared object). In Windows, do not forget to export symbols.