Diving into the KiCad source code
CC Attribution 2.0 Belgium:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Sumiński, Maciej
Let's be sincere, all of us would love to change something in KiCad. I bet youhave an idea for a new tool or another killer feature that would make yourlife so much easier. You know what? You are free to do so! Even more, you are welcome to contributeto the project, and it is not that difficult as one may think. Those who havebrowsed the source code might find it overwhelming at first, but the truth is:you do not have to know everything to create useful extensions. I would like to invite you for a walk through the KiCad source code todemonstrate how easy it is to add this tool you have always been dreamingabout.
 Hello everyone, my name is Mati Smynsky, 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 it solves your problem but then it is not very well advertised. 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. Short example to see how does it look like in real. A few words about what you can do when you are finished with a tool and then some further information if you need it. So building KICAD is really quite straightforward for Linux, you need to install dependencies, 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 M.C.S.2 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. 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 and 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. As we have 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 method 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 is 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, 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 are to. And this is this function. And really that's it. It's in total three lines for this 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. Here's the base class board item, and then most of the classes are, I think, self-explanatory. You have paths, tracks, vias, zones. Well, maybe not info item. It's 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 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 RESTness 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 we can limit the scope. Then you can also define hotkey if you want, a label that is going to appear if you are going to edit a menu, to 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 that, this is the class available for every tool in PCB new, and it has dual role first is 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. Now, there's the constructor. There's even no need for the structure. You just have the three methods, reset init and set transitions, one event handler, and we will have also a context menu. So 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. And 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. We are 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 a context menu. And 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. And simply at the entry. The thing with selection menu, it 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. See 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 the frame that is displaying PCB new. The model, design settings because you want to know for example what are the tracks and bias 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 bias. Well, just illustrate. We need to know what is the distance between one and its neighboring pad. And unfortunately in Kikad, 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 bias, we can iterate again over all pads that are stored in the module. And here first we compute where the bias 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 Viya 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 Kica source code directory, PCB new tools. 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 just, you know, you need to fix the indentation because everyone knows that tabs and spaces are important. And then if you have just a single patch, 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 LungePad. 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 Oxygen, the code formatting rules and all the information that might be useful for you. There's also a tool frame or 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. If it's not, it's the time to ask questions. Okay, two quick questions. Okay, I was wondering if you could say a little bit about plug-in mechanism. Because you talked about Oxygen, but what's the fundamental basis of it? The question was to say a bit more about the plug-in system. Do you mean the tool framework, right? The fundamental concept of the plug-in 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 kick-outs. So it's not the plug-in per se. So it really doesn't have real plug-ins? It has plug-ins for schematics, for schematic formats, as Swain mentioned, and for board formats. So it's just saving and loading the files. So all our stuff, it's not dynamic? Yeah, no, the reason I asked is because of Wayne and Thomas commented about the plug-ins as being something new and I was wondering something similar to the Canoe cap plug-ins. Well, for the tools, they're not real plug-ins. For 3D models, for board files and schematics, they are, oh, sorry, I think for 3D models they can be plug-ins and for everything else there is just the interface. Oh, okay. So yeah, so it's not an extension plug-in 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? 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.
 Hello everyone, my name is Mati Smynsky, 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 it solves your problem but then it is not very well advertised.  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.  Short example to see how does it look like in real.  A few words about what you can do when you are finished with a tool and then some further  information if you need it.  So building KICAD is really quite straightforward for Linux, you need to install dependencies,  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 M.C.S.2 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.  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 and 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.  As we have 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  method 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 is 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, 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 are to.  And this is this function.  And really that's it.  It's in total three lines for this 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.  Here's the base class board item, and then most of the classes are, I think, self-explanatory.  You have paths, tracks, vias, zones.  Well, maybe not info item.  It's 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 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 RESTness 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 we can limit the scope.  Then you can also define hotkey if you want, a label that is going to appear if you are  going to edit a menu, to 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 that, this is the class available for every tool in PCB  new, and it has dual role first is 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.  Now, there's the constructor.  There's even no need for the structure.  You just have the three methods, reset init and set transitions, one event handler, and  we will have also a context menu.  So 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.  And 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.  We are 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 a context menu.  And 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.  And simply at the entry.  The thing with selection menu, it 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.  See 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 the frame that is displaying PCB new.  The model, design settings because you want to know for example what are the tracks and  bias 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 bias.  Well, just illustrate.  We need to know what is the distance between one and its neighboring pad.  And unfortunately in Kikad, 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 bias, we  can iterate again over all pads that are stored in the module.  And here first we compute where the bias 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 Viya 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 Kica source code  directory, PCB new tools.  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 just, you know, you need to fix the indentation because everyone knows that tabs and spaces  are important.  And then if you have just a single patch, 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 LungePad.  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 Oxygen, the code formatting rules and all  the information that might be useful for you.  There's also a tool frame or 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.  If it's not, it's the time to ask questions.  Okay, two quick questions.  Okay, I was wondering if you could say a little bit about plug-in mechanism.  Because you talked about Oxygen, but what's the fundamental basis of it?  The question was to say a bit more about the plug-in system.  Do you mean the tool framework, right?  The fundamental concept of the plug-in 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 kick-outs.  So it's not the plug-in per se.  So it really doesn't have real plug-ins?  It has plug-ins for schematics, for schematic formats, as Swain mentioned, and for board  formats.  So it's just saving and loading the files.  So all our stuff, it's not dynamic?  Yeah, no, the reason I asked is because of Wayne and Thomas commented about the plug-ins  as being something new and I was wondering something similar to the Canoe cap plug-ins.  Well, for the tools, they're not real plug-ins.  For 3D models, for board files and schematics, they are, oh, sorry, I think for 3D models  they can be plug-ins and for everything else there is just the interface.  Oh, okay.  So yeah, so it's not an extension plug-in 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?  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.
Diving_into_the_KiCad_source_code_0_47.png Diving_into_the_KiCad_source_code_48_107.png Diving_into_the_KiCad_source_code_108_17891.png Diving_into_the_KiCad_source_code_17892_19331.png Diving_into_the_KiCad_source_code_19332_20111.png Diving_into_the_KiCad_source_code_20112_20351.png Diving_into_the_KiCad_source_code_20352_25583.png Diving_into_the_KiCad_source_code_25584_25763.png Diving_into_the_KiCad_source_code_25764_26159.png Diving_into_the_KiCad_source_code_26160_28763.png Diving_into_the_KiCad_source_code_28764_28871.png Diving_into_the_KiCad_source_code_28872_28943.png Diving_into_the_KiCad_source_code_28944_29003.png Diving_into_the_KiCad_source_code_29004_29051.png Diving_into_the_KiCad_source_code_29052_29111.png Diving_into_the_KiCad_source_code_29112_29603.png Diving_into_the_KiCad_source_code_29604_29699.png Diving_into_the_KiCad_source_code_29700_29855.png Diving_into_the_KiCad_source_code_29856_29939.png Diving_into_the_KiCad_source_code_29940_29999.png Diving_into_the_KiCad_source_code_30000_30155.png Diving_into_the_KiCad_source_code_30156_30239.png Diving_into_the_KiCad_source_code_30240_33911.png Diving_into_the_KiCad_source_code_33912_34475.png Diving_into_the_KiCad_source_code_34476_34523.png Diving_into_the_KiCad_source_code_34524_34763.png Diving_into_the_KiCad_source_code_34764_36155.png Diving_into_the_KiCad_source_code_36156_36587.png Diving_into_the_KiCad_source_code_36588_37463.png Diving_into_the_KiCad_source_code_37464_37511.png Diving_into_the_KiCad_source_code_37512_37559.png Diving_into_the_KiCad_source_code_37560_37631.png Diving_into_the_KiCad_source_code_37632_37684.png