KiCad 插件系统

本文档由其贡献者授予版权 © 2016,如下所示。您可以根据 GNU 通用公共许可证(http:/www.gnu.org/licenses/gpl.html)版本 3 或更高版本或知识共享许可协议(http:/creativecommons.org/licenses/by/3.0/)、版本 3.0 或更高版本的条款进行分发和/或修改。

本指南中的所有商标均属于其合法所有者。

Contributors

Cirilo Bernardo

翻译

taotieren <admin@taotieren.com>, 2019

Telegram 简体中文交流群: https://t.me/KiCad_zh_CN

反馈

请将任何错误报告、建议或新版本引导到此处:

出版日期和软件版本

2016 年 1 月 29 日出版。

1. KiCad 插件系统简介

KiCad 插件系统是一个使用共享库扩展 KiCad 功能的框架。 使用插件的一个主要优点是在开发插件时没有必要重建 KiCad 套件; 事实上,可以借助 KiCad 源代码树中的一小组标题构建插件。 通过确保开发人员仅编译与正在开发的插件直接相关的代码,从而减少每个构建和测试周期所需的时间,在插件开发期间删除构建 KiCad 的要求极大地提高了工作效率。

插件最初是为 3D 模型查看器开发的,因此可以支持更多类型的 3D 模型,而无需对支持的每种新模型类型的 KiCad 源进行重大更改。 插件框架后来被推广,以便将来开发人员可以创建不同类型的插件。 目前,只有 3D 插件在 KiCad 中实现,但可以想象最终将开发 PCB 插件,以使用户能够实现数据导入器和导出器。

1.1. 插件类

插件分为插件类,因为每个插件都解决了特定域中的问题,因此需要该域独有的接口。 例如,3D 模型插件从文件加载 3D 模型数据并将该数据转换为可由 3D 查看器显示的格式。 PCB 导入/导出插件将获取 PCB 数据并导出为其他电气或机械数据格式,或将外部格式转换为 KiCad PCB。 目前只开发了 3D 插件类,它将成为本文档的重点。

实现插件类需要在 KiCad 源代码树中创建代码来管理插件代码的加载。在 KiCad 源代码树中,文件 ‘plugins/ldr/pluginldr.h’ 声明了所有插件加载器的基类。这个类声明了我们期望在任何 KiCad 插件(样板代码)中找到的最基本的函数,它的实现提供了对插件加载器和可用插件之间的版本兼容性的基本检查。标题 ‘plugins/ldr/3d/pluginldr3D.h’ 声明了 3D 插件类的加载器。加载器负责加载给定的插件并使其功能可用于 KiCad。插件加载器的每个实例代表一个实际的插件实现,并充当 KiCad 和插件功能之间的透明桥梁。加载器不是 KiCad 中支持插件所需的唯一代码:我们还需要代码来发现插件和代码,以通过插件加载器调用插件的功能。在 3D 插件的情况下,发现和调用功能都包含在 S3D_CACHE 类中。

除非正在开发新的插件类,否则插件开发人员不需要关心 KiCad 管理插件的内部代码的细节; 插件只需要定义其特定插件类声明的函数。

标题 ‘include/plugins/kicad_plugin.h’ 声明了所有 KiCad 插件所需的泛型函数; 这些函数标识插件类,提供特定插件的名称,提供插件类 API 的版本信息,提供特定插件的版本信息,并提供插件类 API 的基本版本兼容性检查。 简而言之,这些功能是:

1.1.1. 插件类:PLUGIN_3D

标题 ‘include/plugins/3d/3d_plugin.h’ 声明了必须由所有 3D 插件实现的函数,并定义了插件所需的许多函数以及用户不得重新实现的函数。 用户不得重新现的已定义函数是:

用户必须实现的功能如下:

2. 教程:3D插件类

本节包含对 PLUGIN_3D 类的两个非常简单的插件的描述,并引导用户完成代码的设置和构建。

2.1. 基本的 3D 插件

本教程将引导用户开发一个名为 “PLUGIN_3D_DEMO1” 的非常基本的 3D 插件。 本教程的目的只是为了演示一个非常基本的 3D 插件的构造,除了提供一些允许 KiCad 用户在浏览 3D 模型时过滤文件名的过滤字符串之外什么都不做。 这里演示的代码是任何 3D 插件的绝对最低要求,可以用作创建更高级插件的模板。

为了构建演示项目,我们需要以下内容:

  • CMake

  • KiCad 插件头

  • KiCad 场景图库 ‘kicad_3dsg’

要自动检测 KiCad 标头和库,我们将使用 CMake FindPackage 脚本; 如果相关的头文件安装到 中,则本教程中提供的脚本应该适用于 Linux 和 Windows。

要开始,让我们创建一个项目目录和 FindPackage 脚本:

必须安装 Kicad 及其插件标头; 如果将它们安装到用户目录或 Linux 上的 ‘/opt’ 下,或者您使用的是 Windows,则需要将 ‘KICAD_ROOT_DIR’ 环境变量设置为指向包含 KiCad ‘include’ 和 ‘lib’ 目录的目录。 对于 OS X,此处显示的 FindPackage 脚本可能需要进行一些调整。

要配置和构建教程代码,我们将使用 CMake 并创建一个 ‘CMakeLists.txt’ 脚本文件:

第一个演示项目非常基础; 它由一个文件组成,除了编译器默认值之外没有外部链接依赖项。 我们首先创建一个源目录:

现在我们自己创建插件源:

s3d_plugin_demo1.cpp

此源文件满足实现 3D 插件的所有最低要求。 该插件不会为渲染模型生成任何数据,但它可以为 KiCad 提供支持的模型文件扩展名和文件扩展名过滤器列表,以增强 3D 模型文件选择对话框。 在 KiCad 中,扩展字符串用于选择可用于加载指定模型的插件; 例如,如果插件是 ‘wrl’,那么 KiCad 将调用声称支持扩展 ‘wrl’ 的每个插件,直到插件返回可视化数据。 每个插件提供的文件过滤器将传递到 3D 文件选择器对话框,以改善浏览 UI。

要构建插件:

该插件将被构建但未安装; 如果要加载插件,必须将插件文件复制到 KiCad 的插件目录。

2.2. 高级 3D 插件

本教程将引导用户开发名为 “PLUGIN_3D_DEMO2” 的 3D 插件。 本教程的目的是演示 KiCad 预览器可以渲染的非常基本的场景图的构造。 该插件声称处理 ‘txt’ 类型的文件。 虽然文件必须存在,以便缓存管理器调用插件,但此插件不处理文件内容; 相反,插件只是创建一个包含一对四面体的场景图。 本教程假定第一个教程已完成,并且已创建 CMakeLists.txt 和 FindKICAD.cmake 脚本文件。

将新的源文件放在与上一个教程的源文件相同的目录中,我们将扩展上一个教程的 CMakeLists.txt 文件来构建本教程。 由于这个插件会为 KiCad 创建一个场景图,我们需要链接到 KiCad 的场景图库 ‘kicad_3dsg’。 KiCad 的场景图库提供了一组可用于构建场景图对象的类; 场景图对象是 3D 缓存管理器使用的中间数据可视化格式。 所有支持模型可视化的插件都必须通过此库将模型数据转换为场景图。

第一步是扩展 ‘CMakeLists.txt’ 来构建这个教程项目:

现在我们切换到源目录并创建源文件:

s3d_plugin_demo2.cpp

3. 应用程序编程接口(API)

插件通过应用程序编程接口(API)实现实现。 每个插件类都有其特定的 API,在 3D 插件教程中,我们已经看到了由标题 “3d_plugin.h” 声明的 3D 插件 API 实现的示例。 插件也可能依赖于 KiCad 源代码树中定义的其他 API; 在 3D 插件的情况下,支持模型可视化的所有插件必须与标题 ‘ifsg_all.h’ 及其包含的标题中声明的 Scene Graph API 交互。

本节描述了插件类实现可能需要的插件类 API 和其他 KiCad API 的详细信息。

3.1. 插件类 API

目前只有一个为 KiCad 声明的插件类:3D 插件类。 所有 KiCad 插件类都必须实现头文件 ‘kicad_plugin.h’ 中声明的一组基本函数; 这些声明称为 Base Kicad 插件类。 不存在 Base Kicad 插件类的实现; 头文件的存在纯粹是为了确保插件开发人员在每个插件实现中实现这些定义的函数。

在 KiCad 中,插件加载器的每个实例都实现了插件提供的 API,就像插件加载器是提供插件服务的类一样。 这是通过 Plugin 加载器类实现的,该类提供包含与插件实现的类似的函数名的公共接口; 如果例如没有加载插件,则参数列表可以变化以适应向用户通知可能遇到的任何问题的需要。 在内部,插件加载器使用存储的指针指向每个 API 函数,以代表用户调用每个函数。

3.1.1. API:Base Kicad 插件类

Base Kicad 插件类由头文件 ‘kicad_plugin.h’ 定义。 此标头必须包含在所有其他插件类的声明中; 例如,请参阅头文件 ‘3d_plugin.h’ 中的 3D 插件类声明。 这些函数的原型在 《 plugin-classes(插件-类),Plugin Classes(插件类)》 中简要描述。 API 由 “pluginldr.cpp” 中定义的基本插件加载器实现。

为了帮助理解基本 KiCad 插件头所需的功能,我们必须查看基本插件 Loader 类中发生的情况。 Plugin Loader 类声明了一个虚函数 ‘Open()’,它接受要加载的插件的完整路径。 在特定的插件类加载器中实现 ‘Open()’ 函数最初将调用基本插件加载器的受保护的 ‘open()’ 函数; 这个基础 ‘open()’ 函数试图找到每个必需的基本插件函数的地址; 一旦检索到每个函数的地址,就会强制执行一些检查:

  1. 调用插件 ‘GetKicadPluginClass()’,并将结果与插件加载器实现提供的插件类字符串进行比较; 如果这些字符串不匹配,则打开的插件不适用于 Plugin Loader 实例。

  2. 调用插件 ‘GetClassVersion()’ 来检索插件实现的插件类 API 版本。

  3. 插件加载器虚拟 ‘GetLoaderVersion()’ 函数被调用以检索由加载器实现的插件类 API 版本。

  4. 插件和加载器报告的插件类 API 版本必须具有相同的主版本号,否则它们被认为是不兼容的。 这是最基本的版本测试,它由基本插件加载器强制执行。

  5. 使用插件加载器的插件类 API 版本信息调用插件 ‘CheckClassVersion()’; 如果插件支持给定版本,则返回 “true” 表示成功。 如果成功,加载器根据 ‘GetKicadPluginName()’ 和 ‘GetPluginVersion()’ 的结果创建一个 PluginInfo 字符串,插件加载过程在 Plugin Loader 的 ‘Open()’ 实现中继续。

3.1.2. API:3D 插件类

3D 插件类由头文件 ‘3d_plugin.h’ 声明,它扩展了所需的插件函数,如《class-plugin-3d(类-插件-3d),Plugin Class(插件类):PLUGIN_3D(插件_3D)》中所述。 相应的插件加载器在 ‘pluginldr3D.cpp’ 中定义,除了所需的 API 函数之外,加载器还实现了以下公共函数:

所需的 3D 插件类功能通过以下功能公开:

在典型情况下,用户将执行以下操作:

  1. 创建 ‘KICAD_PLUGIN_LDR_3D’ 的实例。

  2. 调用 ‘Open(“/path/to/myplugin.so”)’ 来打开一个特定的插件。 必须检查返回值以确保根据需要加载插件。

  3. 调用由 ‘KICAD_PLUGIN_LDR_3D’ 公开的任何 3D 插件类调用。

  4. 调用 ‘Close()’来关闭(取消链接)插件。

  5. 销毁 ‘KICAD_PLUGIN_LDR_3D’ 实例。

3.2. 场景图类 API

Scenegraph 类 API 由标题 ‘ifsg_all.h’ 及其包含的标题定义。 API 由许多辅助例程组成,命名空间为 ‘S3D’,在 ‘ifsg_api.h’ 中定义,包装类由各种 ‘ifsg_*.h’ 标题定义; 包装器支持底层的场景图类,它们一起形成一个与 VRML2.0 静态场景图兼容的场景图结构。 标题,结构,类及其公共函数如下:

sg_version.h
sg_types.h

‘sg_base.h’ 头包含 scenegraph 类使用的基本数据类型的声明。

sg_base.h

‘IFSG_NODE’ 类是所有场景图节点的基类。 所有 scenegraph 对象都实现此类的公共函数,但在某些情况下,特定函数可能对特定类没有意义。

ifsg_node.h

‘IFSG_TRANSFORM’ 类似于 VRML2.0 Transform 节点; 它可以包含任意数量的子 IFSG_SHAPE 和 IFSG_TRANSFORM 节点以及任意数量的引用的 IFSG_SHAPE 和 IFSG_TRANSFORM 节点。 有效的场景图必须有一个 “IFSG_TRANSFORM” 对象作为根。

ifsg_transform.h

‘IFSG_SHAPE’ 类似于 VRML2.0 Shape 节点; 它必须包含单个子节点或引用 FACESET 节点,并且可以包含单个子节点或引用 APPEARANCE 节点。

ifsg_shape.h

‘IFSG_APPEARANCE’ 类似于 VRML2.0 Appearance 节点,但目前它只代表包含 Material 节点的 Appearance 节点的等价物。

ifsg_appearance.h

‘IFSG_FACESET’ 类似于包含 IndexedFaceSet 节点的 VRML2.0 Geometry 节点。 它必须包含单个子节点或引用 COORDS 节点,单个子 COORDINDEX 节点以及单个子节点或引用 NORMALS 节点; 另外可能有一个子节点或引用 COLORS 节点。 提供简化的法线计算功能以帮助用户将正常值分配给表面。 与 VRML2.0 模拟的偏差如下:

  1. 法线始终是每个顶点。

  2. 颜色总是每个顶点。

  3. 坐标索引集必须仅描述三角形面。

ifsg_faceset.h
ifsg_coords.h

‘IFSG_COORDINDEX’ 类似于 VRML2.0 coordIdx[] 集,除了它必须专门描述三角形面,这意味着索引的总数可以被 3 整除。

ifsg_coordindex.h

‘IFSG_NORMALS’ 相当于 VRML2.0 Normals 节点。

ifsg_normals.h

‘IFSG_COLORS’ 类似于 VRML2.0 colors[] 集。

ifsg_colors.h

其余的 API 函数在 ‘ifsg_api.h’ 中定义如下:

ifsg_api.h

有关 Scenegraph API 的实际使用示例,请参阅上面的《advanced-3d-plugin(高级-3d-插件),Advanced 3D Plugin tutorial(高级 3D 插件教程)》,以及 KiCad VRML1,VRML2 和 X3D 解析器。