Devel
Devel is a plugin that let you create quickly new plugin skeletons for Graphite. The idea is to create automatically all that can be so you can work on what is important: your code and algorithms.
This page is more of a reference about Devel, for a more hands-on experience, you can go to the Devel Tutorial.
Installation
Devel should be available by default in latest versions of Graphite.
If you don't directly have the Devel menu when you launch Graphite:
- go to File > Preferences > Modules
- add "devel"
- save configuration file
- quit and restart Graphite
Commands
Here is a description of each command available in the Devel menu.
Load Plugin
Dynamically loads a module.
To be available, a plugin must have been built for the current configuration. That is to say that to load a plugin compiled in Debug mode, you need to run a Graphite compiled in Debug mode too.
The best way to load a plugin is to do it at start up, with File > Preferences > Modules. The reason is that sometimes the commands and tools of the plugin won't be available with dynamic loading. This behavior is currently due to the GUI creation mechanism: GUI elements related to a Grob class (commands in the menu bar, tool icons, ...) are created the first time you select one in the scene manager.
In case of loading multiple times a plugin, even if each time it says that loading is successful, only the first one will be effectively taken into account. This also means that you can't reload a plugin, you must restart Graphite in order to load a different version.
Create plugin
Automatically creates a minimal skeleton for your plugin, with the core files needed.
You have to provide a name, and the files created will be in <graphite_root>/../plugins/OGF/<plugin_name>. The following are created :
- configure.sh: configure the plugin's project
- CMakeLists.txt: basic CMake configuration
- CMake/: directory with some helper files for the build system
- common/: directory with the files that makes the project loadable as a Graphite plugin
- algo/: directory where you will put your algorithm files
The plugin name must be unique among all the libraries and plugins, including the packages of Graphite (in <graphite_root>/src/packages/OGF).
Create grob
For a given plugin, creates a new Grob type.
For versions before and including 2.0-a2, the only valid base class is Grob when creating a Grob with Devel, but you could modify the source code to inherit an other Grob class (like Surface for example). For more recent versions, you can use any existing Grob class as a base class.
Be careful when choosing the extension, as the behavior when different Grob are associated with the same extension is undefined and Devel currently does not check for extension uniqueness.
This creates the following gom classes, in their corresponding folders:
- the <grob_name> class, that represents the Graphite object
- a <grob_name>Commands class (abstract)
- a <grob_name>Shader class (abstract), as well as the Plain<grob_name>Shader2d and Plain<grob_name>Shader3d subclasses
- a <grob_name>Tool class (abstract)
The Grob name mustn't be only lower case, at least the first letter should be capital.
Create commands
For a given plugin, creates a new set of commands that will be accessible in the menu bar for the specified type of Grob.
This command creates a class that will contain a set of commands. Available Grob classes are listed in a drop-down box. If you want to create a command for a Grob type you created with Devel and that does not appear in the list, you have to compile your plugin, restart Graphite and load the plugin before opening again the dialog.
The command name will be the one of the class, and will also be used as the name of the menu item that goes in the menu bar. Each function declared after the keyword "gom_slot" will appear as a menu element, which opens a message box where the user can specify the parameters and run the method, exactly like all Devel commands. You can create sub-menus to group your functions with the "menu" attribute.
This will create commands/<command_name>_commands.h and commands/<command_name>_commands.cpp. The class created originally contains only one function, "my_function", which is put in the "my category" sub-menu.
Particular Gom attributes:
menu
Applies to a gom_slot of the command class. This allows to group methods into subcategories.
Create shader
For a given plugin, creates a new shader that inherits an existing shader class.
Shader classes follow the naming convention:
<shader_name><grob_class_name>Shader<dimension>
where:
- <shader_name> is the shader distinctive name, like "Plain", ...
- <grob_class_name> is the name of the Grob class the shader can be applied to
- <dimension> can be 2d or 3d
example: PlainSurfaceShader2d
<grob_class_name>, "Shader" and <dimension> are automatically determined from the base class. For clarity and to avoid redundancy, you should not specify a name containing the Grob name, "Shader" or ending with "2d" or "3d".
Create tool
For a given plugin, creates a new tool that inherits an existing tool class, for the specified type of Grob.
The tool must have a unique name, and the parent tool class can be Tool or any of its derived classes, like SurfaceTool, MultiTool, LineTool...
This will create tools/<tool_name>.h and tools/<tool_name>.cpp, with a very basic structure that can fit any tool you could want to make.
By default, the created tool has the abstract gom attribute set to "true". You may want to create a hierarchy of tools, and this allows to flag which tool is just meant to be a superclass, and not instantiated.
Up to Graphite 2.0-a2, the Tool classes are named following the pattern <tool_name><grob_class_name>Tool. The highest abstract tool class associated to a Grob (which is a base class of all the tools that acts on this Grob type) is named <grob_class_name>Tool.
Exemple : VertexPickerSurfaceTool for a tool targeting Surface.
Newer versions use the same convention as the rest of Graphite, that is to say: <grob_class_name><tool_name>Tool.
Particular Gom attributes:
category
Specifies in which box a Tool will be added.
gom_attribute(category,"foo") ; // will be added to a "foo" box
icon
An icon can be specified for a Tool.
gom_attribute(icon,"my_icon") ; //corresponds to GRAPHITE_ROOT/lib/icons/my_icon.xpm)
help
Specifies the help bubble associated with a Tool.
gom_attribute(help,"this tool does that!") ;
message
The message is displayed in the status bar when this tool is selected.
gom_attribute(message,"Show this in status bar when selected!") ;
Create class
For a given plugin, creates a new empty class, and if needed the sub-directory to put it.
This command creates <sub-directory>/<class_name>.h and <sub-directory>/<class_name>.cpp. These files have the empty class declaration, with the Graphite header, protection against double inclusion, OGF namespace declaration and some necessary includes. Inheritance is not provided by Devel, but can be added by directly editing the files.
If the sub-directory is created, it is also automatically added to the CMakeLists.txt.
Create file
For a given plugin, creates a new pair of .h/.cpp files, and if needed the sub-directory to put them.
This command creates <sub-directory>/<file_name>.h and <sub-directory>/<file_name>.cpp. These files have the Graphite header, protection against double inclusion, OGF namespace declaration and some necessary includes.
If the sub-directory is created, it is also automatically added to the CMakeLists.txt.
Building plugins
Once you have created the skeleton of your plugin and populated it with various elements, you have to build it.
1) Prerequisites:
- Same as for building Graphite. See the Windows or Linux guide.
- A fully built Graphite of the same configuration (Debug, Release...) you want to build your plugin for.
2) Prepare build
Windows: Run Cmake with:
Directory: <plugin_dir> Build directory: <plugin_dir>\build\Windows
Linux: in <plugin_dir>:
./configure.sh
3) Build
Windows: open the solution found in <plugin_dir>/build/Windows and build it for each configuration you are interested in.
Linux: in <plugin_dir>/build/Linux-<configuration>:
make
4) Load plugin
To use a plugin, you have to explicitly load it in Graphite. You can do this in two ways:
- If you just want to load it once, when needed, you can use the Load plugin command of Devel.
- If you want the plugin to be loaded automatically when launching Graphite, add its name to File > Preferences > Modules .
Limitations
- no plugin unload nor reload, you have to restart Graphite to test a new version of the plugin you are working on.
gom attributes
Special attributes can be given to Gom classes. This allows to let Gom know about some more meta information about the class. Here is a complete list of the ones currently used in Graphite.
- abstract
- superclass
- menu
- category
- icon
- help
- message
- continuous_update
Tips
- You can use the GEL Terminal (GEL > Show terminal) to have a better look at what is going on.
- Each time you modify the plugin structure (adding or removing directories and files), you have to reconfigure the project before building it again.
- If you want later to remove a command, a shader or a tool, you have to remove the referring lines in common/<plugin_name>_common.cpp too (includes and
ogf_register...). - In case of inexplicable bug at loading, try deleting the build directory and the plugin's .dll or .so file in <Graphite_dir>/build/<configuration>/binaries/lib, then reconfiguring/rebuilding the plugin.
- Even if in some cases you could use lower-case names for elements created with Devel, it's a good habit to keep the same naming convention as the rest of the program, by using names with the first letter
Troubleshooting
- VC++ complains that an error occurred when "Generating gomgenerated.cpp", during compilation.
- This error usually happens when you are trying to compile the plugin for a configuration in which Graphite has not been built. Verify that you are compiling you plugin in the desired configuration and try recompiling Graphite in the same configuration.
- VC++ complains about "syntax error : identifier '<your_grob_class_name>'"
- This error occurs when you create a new Grob with a lower-case name. The skeleton generated uses a lower-case version of the Grob name for methods or variables and if the name is already lower-case, it obviously can't go well. Either delete all the files related to this Grob and start again with a correct name (with at least one capital letter) or, if you are not afraid of tedious work, edit all references to the class.
- My tools/commands/whatever are created multiple times when I load my plugin!
- You may have created multiple times your tool/command/whatever, for example by cliquing "Apply" then "OK" in the creation dialog. To remove the redundant instances, edit common/<plugin_name>_common.cpp to let only one
ogf_register_xxxxfor the duplicated element. You can also remove the extra includes.
- You may have created multiple times your tool/command/whatever, for example by cliquing "Apply" then "OK" in the creation dialog. To remove the redundant instances, edit common/<plugin_name>_common.cpp to let only one
Example
See Devel Tutorial