 Hello everyone, my name is Matej Smynski, some of you may know me as Orson, I work at CERN and for the past few years I have been regularly contributing to KICAD and I am going to start with maybe not very humble statement but I think KICAD is a really great tool, it has a lot of awesome utilities and it also has a text format which is a really good thing because it plays well with Git, with other service version control but it is also abused in certain ways because due to the nature of human readable formats, people are tempted to change the manual or write external scripts that do what is missing in KICAD. The problem is when you manually edit a file, well it is a one time solution, when you write an external script, well it solves your problem but then it is usually not very well advertised. And if the file format changes you need to fix it and stuff like that, so perhaps maybe a better idea would be to write code directly for KICAD, have the problem solved once and for all and give back to community and have everyone take advantage of that. So today I would like to tell you how is it done in KICAD, how easy is the interface for creating new tools and to start with we need to know how to build KICAD, it is not a very big deal, then a few words about the tool framework, I think that is the main point here, the interface for creating new tools, a few useful classes so you know what you can use for dealing with certain problems when writing tools, a short example to see how does it look like in real, a few words about what you can do when you are finished with the tool and then some further information if you need it. So building KICAD is really quite straightforward for Linux, you need to install dependency, it is just a bunch of libraries that usually you can get with your package manager of choice and then these five comments will get you a binary and well that is a good starting point for further development. For Windows it seems to be harder but since MCS2 people created a really good environment for development under Windows, it is really almost the same thing, you just install certain packages and actually it is even shorter than with Linux, you have three comments here so it is really easy to start. Ok so for the tool framework, the tool framework is currently only available for PCB new but we are going to port it to the schematic editor as well to have the same way for creating tools in both applications and probably share some of the code. There are three major subsystems, this is done to speed responsibilities to keep the code cleaner. The first one is Vue, it handles displaying objects in the rendering process. Then you have Model, so all kinds of items that you can find either on your board or on schematics. And then the tool framework which is the code that modifies the model, the thing that you are going to work with. So here is the basic skeleton for a tool. There is a base class called PCB tool and from that you have to implement only a few functions to create a new tool. So with every C++ class there is a constructor and a destructor, nothing very special here you can initialize or free your resources. Then there is a reset method where you can react to certain events, for example when you first start a tool or when the model is reloaded, so for example if you keep pointers you probably need to update them because they might not be valid anymore or when the rendering engine is switched and so on. So you have a chance to react here before anything bad happens. Then there is also the init method and it is different from the constructor in that matter that all the other tools are already created when the init method is called. So if you need to cooperate with something else, that's the right moment to use the tool manager, I will show you later, to use the tool manager to use another tool. And there are also transitions, the set transitions method associates event handlers with particular methods in the class. So if you have, let's say here in this example, if event A arrives then event handler is responsible for handling the event. And here's an example event handler. There are two main ways of implementing handlers. One is a single action, so if there is an event you perform a certain list of operations and you finish. Like you can change position, maybe rotate, flip or stuff like that. Or you can write interactive tools and here you can have a while loop. You can keep receiving events until you decide that you are done. So for example, if you want to create a drawing tool, first you obtain the first click position, then you wait for another one. Then you can draw a line between them. And until the user decides to cancel the tool or well it's up to you. Apart from creating a new tool, I mean coding it, you need to add it to the project. And Kikad uses CMake, so for that you need to modify CMake lists. You need to just add your file there. And you also need to notify PCBNU that there is a new tool that you can use. And for that, in this particular file you just add a new header. If you're a tool. And this is this function. And really that's it. It's in total three lines for registering a new tool. About useful classes. Everything in Kikad that you can modify, I mean for model, is based on EDA item. It's a quite vast hierarchy. So here I can only show you the items related to layout. There's the base class board item. And then, well, most of the classes are, I think, self-explanatory. You have pads, tracks, vias, zones. Well, maybe that info item is not a clear thing. But it's a data structure that helps information about nets. So you can check their name or net code. Probably you will also need that at a certain point. Then when it comes to the UI interface, which are called frames in WXWjust nomenclature. So here again, I had to restrict the hierarchy only to the board related classes. But it's also, I think, quite clear what every of the class does. And most likely you are going to work with these two guys. One is the footprint editor and the other one is layout editor. And usually this is the place where you add your tools. Then we also have a notion of commit. We realize that there are, when writing tools, there are certain parts of code that are repeated. For example, when you add a new item, then you need to create an undo entry so it can be reverted later. Update the board, update view. Well, if you are modifying connected items, then Rastness has to be updated. So in order to avoid problems, potential problems that probably would happen if someone forgot about one of these operations, we created commit. And if you are familiar with Git, probably it looks quite clear. Create a commit, then you decide what kind of changes you want to introduce, either creating new items, removing them. For modification, you need to first save the state because if you first modify the item and then you save the state, then, well, it's already too late for storing changes. And then once it's pushed, commit takes care of updating all the interested parties. So that's it about modifying other subsystems. There are also two actions. Two actions represent an activity that you can perform in PCB new. So for example, if you are writing an action to flip a component, to flip a selection, you just create a tool action that is named usually in a way that first you have the tool, the application, then there's the parent tool and there's the action that is performed. You can decide whether the action is global. So for example, it can apply to all tools or it might be just related to a certain tool. So you can limit the scope. And you can also define hotkey if you want, a label that is going to appear if you are going to add it to a menu, to a right-click context menu, and a hint that will appear when you hover the mouse over the entry, and perhaps an icon if you want. And last but not least is the tool manager. And the tool manager is the class available for every tool in PCB new. And it has dual role versus to let you interact with other tools. For example, if you need to know what is selected, then you just ask the selection tool for the currently selected set of items. Or maybe you can decide to clear the current selection, whatever, you just need to see what other tools offer. And it also allows you to access objects that you are going to use when writing tools. View if you want to add some drawings. Model for modifying the board itself. Or edit frame if you want to deal with the user interface. So now to see an example. I decided to create a simple tool just to illustrate how is it done in Keycard. And it's going to be a funnel tool. So if you have a high pin count package, it's just impossible to route all the pads using a single layer. So instead you need to draw a short piece of track and use a Viya to use other layers for routing. So our tool is going to create all the tracks and vias, and after that the routing should be much easier for you. The code that I'm going to show in a moment is currently available on Launchpad. So if you want to study it or maybe upgrade it because it's very simple to write now, then you are free to have a look at it. So here we have the header file. It really resembles the one that I have shown you before. Well, there's the constructor. There's even no need for this tractor. You just have the three methods. Reset, init, and set transitions. One, event handler. And we'll have also a context menu. And for that we are just storing the pointer to the menu that we are going to create. And the more interesting part is the CPP file. So skipping the license. It's important thing that don't forget about it when you are writing code. First, you add all the headers that you are going to use. There are a few that probably you are going to use in most of the tools like tool actions, menus, tool manager, and commit. Then because we are going to deal with modules, you need to know about the class that is going to be modified. And I want to also involve selection tool because I want to operate on the object that is currently selected. Then we define the tool action for that. So it's again really the same thing that I have shown on the previous slide. Constructor, really empty because there is nothing to initialize apart from the base class. Reset, also simple because there are no cases when we have to deal with reloading the model, for example. And then the init function. Here you are going to create context menu. So first we grab the selection tool because the selection tool also offers the right click context menu that is displayed when you right click on something. We create menu, the menu that we are going to put our actions in. Simply at the entry, the thing with selection menu has a feature allowing you to decide when your menu is going to appear. So for that there are also selection conditions. So for example here you can decide that the menu has to be shown only when you have selected modules. There are a few basic selection conditions that you can join using and or operators. And that's about it. That's our init method. So transitions, very short. Just run the action fun out method. Just run the fun out method when action fun out arrives. And here is the most interesting part. We just get a few objects that you are going to use when writing the tool. The selection tool, sorry, the selection itself from the selection tool. The frame, the window that is hosting our, well, the frame that is displaying PCB new. The model design settings because you want to know for example what are the tracks and vias size that are currently used in the design. And commit for storing our changes. Now the first step that we need to do is to compute the distance between the vias. Well, just illustrate. We need to know what is the distance between one and its neighboring pad. And unfortunately in kick out they are not sorted in any special way. So in order to find out what was the distance, you just need to pick the first pad and then iterate over the whole array and just find out what is the shortest distance and is going to be this segment, this distance. So here we take the module. From the module we take the pad. We obtain the position and the size of the module. And later this is the iteration loop that I just described. We just get the position of every pad. We check the coordinates and then later we compute the distance. If it's smaller than what we already computed and probably this is the distance between the two pads. Now when we have all the information that we need for creating the tracks and vias, we can iterate again over all pads that are stored in the module. And here first we compute where the vias should be placed. Later we create a new track. We set all properties like layer, where does it start, where does it end, the net that it has assigned with taking advantage of the board settings class. Similar thing applies for the Viya. It's very similar and both objects are later added to the commit. And this is the part that is done for every pad in the module. And when you have all tracks and vias, you just push it and it's done. So just to show you how does it work, I have already pre-compiled version. So let's say you have a board like this and there's a BGA that you want to route. So when you select it and right click, there's the context menu that we have created and the entry that is a counterpart of the collection that was added in the CPP file. And that's it. It just creates the tracks and vias. If you want, we can change the vias size used for the... Change the size of the vias that are created here, the track size, and they are going to be used here. So that's about it. And then perhaps you would like to see how are other tools implemented. So if you want a few simple examples, I really recommend you to look in the KeyCAD source code directory, PCBNewTools. And there are three tools that are really worth studying. I think they are well documented and they can provide you examples that are worth following. Okay, now if you have created a tool, one thing is to check your code formatting because usually it does the part when there is something wrong. But sincerely, if it's only the code formatting, then you don't really need to be worried too much. You need to fix the indentation because everyone knows that tabs and spaces are important. And then if you have just a single page, you can send it to the developer's mailing list. Or if it's a bigger feature, it's quite convenient to create a merge request on Launchpad. Now if you need some more information, there are a few links. If I had to pick only one, I would go for the first one. There's a dedicated page for developers. So there you can find the documentation in DoxyGen, the code formatting rules, and all the information that might be useful for you. There's also a tool framework tutorial. So it basically explains the concepts that I told you about today. And if you prefer human interaction, there is also the quite active developer mailing list. And then IRC channel on FreeNodeNet, the developers are spread around the world so you can find someone in every time zone, every time of day. And I hope it's much clearer right now. And if it's not, it's the time to ask questions. One quick question. Okay, two quick questions. Okay, I was wondering if you could say a little bit about the plugin mechanism. Because you talked about other things, but what's the fundamental basis of it? The question was to say a bit more about the plugin system. Do you mean the tool framework, right? The fundamental concept of the plugin system, how does it work? Well, here, there's the interface that, well, you can interact with the board. I mean, for the tools, it's not like you have a shared library that is compiled somewhere outside of the tree. So all the tools are compiled and linked setically with kickouts. So it's not the plugin per se. So it really doesn't have real plugins? It has plugins for schematics, for schematic formats, as Wayne mentioned, and for board formats. So it's just saving and loading the files. So all are static, it's not dynamic? No, the reason I asked is because Wayne and Thomas commented about the plugins as being something new. And I was wondering something similar to the canoe cap plugins. Well, for the tools, they are not real plugins. For 3D models, for board files and schematics, they are... Oh, sorry. I think for 3D models, they can be plugins. And for everything else, there is just the interface. Oh, okay. So it's not an extension plugin system? Yeah. Is the same process also for interactive tools, or is there more to know about this? The question is, is the process the same for the interactive tools and the example that I have shown, right? Yeah. So, well, basically, yes, the only difference is how you write the event handler, because you can have a while, keep receiving events, and then you can react to them. Okay, but painting, I have to do myself then. If you modify the object and use the board commit, it will be done for you. Yeah, but during editing, I have to paint myself. No, no, if you modify it and use board commit, it's done.