Introduction to the KiCad plugin system

The KiCad plugin system is a framework for extending the capabilities of KiCad using shared libraries. One of the main advantages of using a plugin is that it is not necessary to rebuild the KiCad suite while developing a plugin; in fact, plugins can be built with the aid of a very small set of headers from the KiCad source tree. Removing the requirement to build KiCad during plugin development greatly increases productivity by ensuring that the developer only compiles code directly related to the plugin which is being developed and thus reducing the time required for each build and test cycle.

Plugins were initially developed for the 3D model viewer to make it possible to support more types of 3D models without requiring major changes to the KiCad source for each new model type supported. The plugin framework was later generalized so that in the future developers can create different classes of plugins. Currently only 3D plugins are implemented within KiCad but it is envisioned that a PCB plugin will eventually be developed to make it possible for users to implement data Importers and Exporters.

Plugin Classes

Plugins are divided into Plugin Classes since each plugin addresses problems in a specific domain and therefore requires an interface unique to that domain. For example, the 3D model plugins load 3D model data from files and translate that data into a format which can be displayed by the 3D viewer. A PCB Import/Export plugin would take PCB data and export to other electrical or mechanical data formats, or translate a foreign format into a KiCad PCB. At the moment only the 3D Plugin Class has been developed and it will be the focus of this document.

Implementing a Plugin Class requires creating code within the KiCad source tree which manages the loading of plugin code. Within the KiCad source tree, the file plugins/ldr/pluginldr.h declares the base class for all plugin loaders. This class declares the most basic functions which we would expect to find in any KiCad plugin (boilerplate code) and its implementation provides basic checks on version compatibility between the plugin loader and the available plugins. The header plugins/ldr/3d/pluginldr3D.h declares a loader for the 3D Plugin Class. The loader is responsible for loading a given plugin and making its functions available to KiCad. Each instance of a plugin loader represents an actual plugin implementation and acts as a transparent bridge between KiCad and the plugin’s features. The loader is not the only code required within KiCad to support plugins: we also need code to discover the plugins and code to invoke the functions of the plugins via the plugin loader. In the case of the 3D plugins the discovery and invocation functions are all contained within the S3D_CACHE class.

Plugin developers do not need to be concerned with the details of KiCad’s internal code for managing plugins unless a new Plugin Class is being developed; a plugin only needs to define the functions declared by their specific plugin class.

The header include/plugins/kicad_plugin.h declares the generic functions required of all KiCad plugins; these functions identify the Plugin Class, provide the name of the specific plugin, provide version information for the Plugin Class API, provide version information for the specific plugin, and provide a basic version compatibility check on the Plugin Class API. In brief, these functions are:

  1. /* Return a UTF-8 string naming the Plugin Class */
  2. char const* GetKicadPluginClass( void );
  3. /* Return version information for the Plugin Class API */
  4. void GetClassVersion( unsigned char* Major, unsigned char* Minor,
  5. unsigned char* Patch, unsigned char* Revision );
  6. /*
  7. Return true if the version check implemented in the plugin
  8. determines that the given Plugin Class API is compatible.
  9. */
  10. bool CheckClassVersion( unsigned char Major,
  11. unsigned char Minor, unsigned char Patch, unsigned char Revision );
  12. /* Return the name of the specific plugin, for example "PLUGIN_3D_VRML" */
  13. const char* GetKicadPluginName( void );
  14. /* Return version information for the specific plugin */
  15. void GetPluginVersion( unsigned char* Major, unsigned char* Minor,
  16. unsigned char* Patch, unsigned char* Revision );

Plugin Class: PLUGIN_3D

The header include/plugins/3d/3d_plugin.h declares the functions which must be implemented by all 3D plugins and defines a number of functions which are required by the plugin and which the user must not reimplement. The defined functions which the user must not reimplement are:

  1. /* Returns the Plugin Class name "PLUGIN_3D" */
  2. char const* GetKicadPluginClass( void );
  3. /* Return version information for the PLUGIN_3D API */
  4. void GetClassVersion( unsigned char* Major, unsigned char* Minor,
  5. unsigned char* Patch, unsigned char* Revision );
  6. /*
  7. Performs basic version checks enforced by the developers of
  8. the loader for the PLUGIN_3D class and returns true if the
  9. checks pass
  10. */
  11. bool CheckClassVersion( unsigned char Major, unsigned char Minor,
  12. unsigned char Patch, unsigned char Revision );

The functions which the user must implement are as follows:

  1. /* Return the number of extension strings supported by the plugin */
  2. int GetNExtensions( void );
  3. /*
  4. Return the requested extension string; valid values are 0 to
  5. GetNExtensions() - 1
  6. */
  7. char const* GetModelExtension( int aIndex );
  8. /* Return the total number of file filters supported by the plugin */
  9. int GetNFilters( void );
  10. /*
  11. Return the file filter requested; valid values are 0 to
  12. GetNFilters() - 1
  13. */
  14. char const* GetFileFilter( int aIndex );
  15. /*
  16. Return true if the plugin can render this type of 3D model.
  17. In some cases a plugin may not yet provide a visual model
  18. and must return false.
  19. */
  20. bool CanRender( void );
  21. /* Load the specified model and return a pointer to its visual model data */
  22. SCENEGRAPH* Load( char const* aFileName );