← Back to team overview

kicad-developers team mailing list archive

A way to convert kicad to new internal units


Note: Subject changed from: Re: Metric and English grids sizes.

--- In kicad-devel@xxxxxxxxxxxxxxx, Wayne Stambaugh <stambaughw@...> wrote:
> The units for .pcb and .mod files are 0.0001". The units for .sch and
> .lib files are 0.001". This will break every Kicad file format except
> the project file although it make break some of settings in it. You
> will not likely make many friends unless you provide complete backwards
> compatibility with the current file formats. You would have to rewrite
> the file parsers to handle the new units and modify the current file
> parsers to convert the current file format to the new units internally.
> You will also have to modify all the code in Kicad that manipulates the
> current units. It will be one hell of a patch:)
> Wayne

You're right, backwards compatibility is a must, and doing it as one big patch will be a major pain (virtually impossible) due to other devel work.

I've given this some thought, and metric grids and coords is a pain, due tothe rounding errors, so I still think it would be worth doing.
It'll have to be done in stages though, some of which will take "sligthly" longer than others:

First, introduce a new header file that defines the internal unit, which must initially be set to the current value (1mil resp. 1dmil for eeschema resp. pcbnew/cvpcb).
The header file must also include a number of conversion routines in the form of #define's, macros and/or inline functions, which eventually must become the only valid way of manipulating units (internal and external).
Also, the type (currently double, 32bit int in the future) of all coordinates, etc., must be defined here, and routines for pretty-printing of coords also belongs here, I think.

Second, add a single-line comment to each and every source file (C++ and maybe the header files as well) that states, that this file hasn't been inspected for change of internal unit yet.

Third, inspect the source (yes, that's right, all 180k+ lines of it ...) and change it to use the new unit defines/macros/functions and typedef.
This can be done a few files at a time, and will hopefully only require major changes to a limited number of files (fingers crossed).
When a file has been inspected/changed, replace the "not-inspected" commentwith a "#include <internalunit.h>" or a comment saying
"file independent on the internal unit", as the case may be.

This third step will take some time (TM), but can be taken a byte (pun intended :-) at a time, just like eating an elephant (eventually, you will be done) ...
Also, it can be shared between several, to speed up the process.

Both the "not-inspected" and "independant" comments and the #include shouldbe unique and easily recognizable.
This means greppable, preferably yielding all three possibilities (and onlythose) with a single, well chosen pattern :-)

Fourth, when all code has been visited, change the internal unit in the header file to 100nm (or one IU, 1kÅ, 1decimicron, ...), and we're done.

This four-step process will change the internal unit, but will keep everything else unchanged, so file formats will be the same, but the code that reads/writes them does something different (converts to/from another unit).

After this (or in parallel), the code that reads/writes files can be enhanced to include support for new fileformats, which supports the new unit, i.e. allows saving the exact coord values, instead of rounding everything off to 1mil resp. 1dmil.

The ability to read the current fileformats must of course be retained "forever", and when saving files, a choice between old or new format must be given - a per-project setting will probably be the best solution, and will provide backwards compatibility if you need it, or better metric precision ifyou don't.
At least initially, the default should be "use the old units".

The new file formats can be made virtually identical to the current ones, by adding only an "InternalUnit" line near the top, and an increase in version number, to signal to older kicad programs that this file is incompatible.

If there are other planned features that will also require an incompatible change (pad stacks ?), include these as well, so that only one new (set of)format(s) is required.

One other thing needs to be addressed, and that is the library files included with kicad.
The eeschema .lib and the pcbnew .mod/.mdc files can be provided in two variants, and the same can be done with the 3D .wrl files, just choose a naming scheme that ensures zero risk of filename collision.

I'm working on a new set of libs for pcbnew (see msg #3358), where all parts are defined by their dimensions and some perl code, so providing both oldand new format libs would be pretty easy (will require only a dozen or so extra lines of code).

What about eeschema - it would be nice to be able to choose between mil andmm based grids (i.e. pin and trace spacing) in eeschema as well ?
This could be done by providing two versions of all parts, or better yet, if all pins are created on a common grid, the parts can simply be scaled between e.g. 100mil (2.54mm) and 2.5mm, depending on your choice between imperial or metric grid.


Follow ups