CUCP#40, file format details: segment/status - by Karl Hammar

(regarding svn diff -r24438:24439 src_plugins/io_kicad/read.c)

I believe the status values are hexadecimal and are bitmaps as defined
in kicad/include/base_struct.h line 105..142 and used or'ed to set
STATUS_FLAGS in line 178.

Only values:
  40000 TRACK_LOCKED
 400000 BEGIN_ONPAD
 800000 END_ONPAD
seems to be of importance.

For details, see the chaos below.

////////////////////////

I found out that I can lock the segment:
right clicking a segment/track (in kicad) gives a popup menu with an 
entry "set flags"-> submenu, with lock track, lock net. I managed to
lock the track and the diff is:

$ diff cucp/Karl/kicad_4.0.7/40_normal.kicad_pcb  cucp/Karl/kicad_4.0.7/40_track_locked.kicad_pcb 
109c109
<   (segment (start 104 105) (end 116 105) (width 0.25) (layer F.Cu) (net 0))
---
>   (segment (start 104 105) (end 116 105) (width 0.25) (layer F.Cu) (net 0) (status 40000))


///

To find out about the use I did:

locate kicad_pcb | grep 'kicad_pcb$' | while read a; do echo "$a:"; grep status "$a"; done > ~/data

grep -v segment data | sed -e 's/via.*status/via ... \(status/' |uniq -c
     28   (via ... (status 30))

## 28 = 2*14 which is installed 5.1.0 matches + matches from git repo., i.e. via/status is new for v5

grep segment data | sed -e 's/segment.*status/segment ... \(status/' | sort | uniq -c
    523   (segment ... (status 10))
      1   (segment ... (status 1000000))
     24   (segment ... (status 2))
    633   (segment ... (status 20))
    196   (segment ... (status 30))
   3638   (segment ... (status 400))
     30   (segment ... (status 400000))
      2   (segment ... (status 400810))
     21   (segment ... (status 402))
   2625   (segment ... (status 420))
    587   (segment ... (status 430))
   5542   (segment ... (status 800))
     28   (segment ... (status 800000))
      4   (segment ... (status 800020))
      6   (segment ... (status 800420))
     27   (segment ... (status 802))
   3894   (segment ... (status 810))
      2   (segment ... (status 820))
    494   (segment ... (status 830))
   2075   (segment ... (status C00))
     14   (segment ... (status C00000))
      2   (segment ... (status C00030))
     27   (segment ... (status C02))
     10   (segment ... (status C10))
      8   (segment ... (status C20))
   1353   (segment ... (status C30))

I.e. teese are the values used:

 2
 10
 20
 30
 400
 402
 420
 430
 800
 802
 810
 820
 830
 C00
 C02
 C10
 C20
 C30
 400000
 400810
 800000
 800020
 800420
 C00000
 C00030
 1000000

and they are probably hexadecimal (since the C).

/// Looking at what kicad installs, v4.0.0, v4.0.1, v4.0.7
(Versions v4.0.0, v4.0.1, v4.0.7 all gives the same numbers.)

find /usr/local/kicad_4.0.7/ -type f -name \*.kicad_pcb -print0 |
xargs -0 grep status |
cut -f2- -d: |
sed -e 's/segment.*status/segment ... \(status/' |
sed -e 's/via.*status/via ... \(status/' |
sort |
uniq -c 
     49   (segment ... (status 10))
      8   (segment ... (status 2))
     28   (segment ... (status 20))
      8   (segment ... (status 30))
   1047   (segment ... (status 400))
      7   (segment ... (status 402))
    343   (segment ... (status 420))
     53   (segment ... (status 430))
   1646   (segment ... (status 800))
      9   (segment ... (status 802))
    362   (segment ... (status 810))
     70   (segment ... (status 830))
    645   (segment ... (status C00))
      9   (segment ... (status C02))
     47   (segment ... (status C30))

/// Looking at what kicad installs, v5.1.0:

find /usr/local/kicad_5.1.0/ -type f -name \*.kicad_pcb -print0 |
xargs -0 grep status |
cut -f2- -d: |
sed -e 's/segment.*status/segment ... \(status/' |
sed -e 's/via.*status/via ... \(status/' |
sort |
uniq -c 
    148   (segment ... (status 10))
    246   (segment ... (status 20))
     62   (segment ... (status 30))
    219   (segment ... (status 400))
     11   (segment ... (status 400000))
      1   (segment ... (status 400810))
    798   (segment ... (status 420))
    214   (segment ... (status 430))
    264   (segment ... (status 800))
     11   (segment ... (status 800000))
      2   (segment ... (status 800020))
      3   (segment ... (status 800420))
   1404   (segment ... (status 810))
      1   (segment ... (status 820))
    142   (segment ... (status 830))
     63   (segment ... (status C00))
      6   (segment ... (status C00000))
      1   (segment ... (status C00030))
      5   (segment ... (status C10))
      4   (segment ... (status C20))
    606   (segment ... (status C30))
     14   (via ... (status 30))

///

In kicad git file kicad/include/base_struct.h:
==============================
// These define are used for the .m_Flags and .m_UndoRedoStatus member of the
// class EDA_ITEM
//
// NB: DO NOT ADD FLAGS ANYWHERE BUT AT THE END: THE FLAG-SET IS STORED AS AN INTEGER IN FILES.
//
#define IS_CHANGED     (1 << 0)    ///< Item was edited, and modified
#define IS_LINKED      (1 << 1)    ///< Used in calculation to mark linked items (temporary use)
#define IN_EDIT        (1 << 2)    ///< Item currently edited
#define IS_MOVED       (1 << 3)    ///< Item being moved
#define IS_NEW         (1 << 4)    ///< New item, just created
#define IS_RESIZED     (1 << 5)    ///< Item being resized
#define IS_DRAGGED     (1 << 6)    ///< Item being dragged
#define IS_DELETED     (1 << 7)
#define IS_WIRE_IMAGE  (1 << 8)    ///< Item to be drawn as wireframe while editing
#define STARTPOINT     (1 << 9)
#define ENDPOINT       (1 << 10)
#define SELECTED       (1 << 11)
#define SELECTEDNODE   (1 << 12)   ///< flag indicating that the structure has already selected
#define STRUCT_DELETED (1 << 13)   ///< flag indication structures to be erased
#define CANDIDATE      (1 << 14)   ///< flag indicating that the structure is connected
#define SKIP_STRUCT    (1 << 15)   ///< flag indicating that the structure should be ignored
#define DO_NOT_DRAW    (1 << 16)   ///< Used to disable draw function
#define IS_CANCELLED   (1 << 17)   ///< flag set when edit dialogs are canceled when editing a
                                   ///< new object
#define TRACK_LOCKED   (1 << 18)   ///< Pcbnew: track locked: protected from global deletion
#define TRACK_AR       (1 << 19)   ///< Pcbnew: autorouted track
#define FLAG1          (1 << 20)   ///< Pcbnew: flag used in local computations
#define FLAG0          (1 << 21)   ///< Pcbnew: flag used in local computations
#define BEGIN_ONPAD    (1 << 22)   ///< Pcbnew: flag set for track segment starting on a pad
#define END_ONPAD      (1 << 23)   ///< Pcbnew: flag set for track segment ending on a pad
#define BUSY           (1 << 24)   ///< Pcbnew: flag indicating that the structure has
                                   ///< already been edited, in some functions
#define HIGHLIGHTED    (1 << 25)   ///< item is drawn in normal colors, when the rest is darkened
#define BRIGHTENED     (1 << 26)   ///< item is drawn with a bright contour

#define DP_COUPLED     (1 << 27)   ///< item is coupled with another item making a differential pair
                                   ///< (applies to segments only)
#define UR_TRANSIENT   (1 << 28)   ///< indicates the item is owned by the undo/redo stack


#define EDA_ITEM_ALL_FLAGS -1

typedef unsigned STATUS_FLAGS;

/**
 * Class EDA_ITEM
 * is a base class for most all the KiCad significant classes, used in
 * schematics and boards.
 */
class EDA_ITEM : public KIGFX::VIEW_ITEM
{
...
protected:
...
    /// Flag bits for editing and other uses.
    STATUS_FLAGS  m_Flags;

...
==============================

in cucp/Karl/kicad_4.0.7/40_track_locked.kicad_pcb we have a (status 40000),
and 0x40000 = 1<<18 which is the define for TRACK_LOCKED above.

If the status value  are bitmaps (flags), theese are the flags used, their bit
position, the define according to the .h file, and the produced file
verifying this:

      2   1  IS_LINKED
     10   4  IS_NEW
     20   5  IS_RESIZED
    400  10  ENDPOINT
    800  11  SELECTED
  40000  18  TRACK_LOCKED  40_track_locked.kicad_pcb
 400000  22  BEGIN_ONPAD   40_22.kicad_pcb
 800000  23  END_ONPAD     40_22.kicad_pcb
1000000  24  BUSY

currently don't know how to verify the others.

///

In installed dir. /usr/local/kicad_4.0.7/share/kicad/demos/ecc83/

fgrep "(status 400)" ecc83-pp.kicad_pcb 
  (segment (start 142.875 100.965) (end 138.43 100.965) (width 0.8636) (layer Cuivre) (net 2) (status 400))
  (segment (start 159.385 117.475) (end 164.465 117.475) (width 0.8636) (layer Cuivre) (net 5) (status 400))
  (segment (start 149.86 128.905) (end 150.495 129.54) (width 0.8636) (layer Cuivre) (net 6) (status 400))
  (segment (start 151.54148 107.7722) (end 152.6794 108.91012) (width 0.8636) (layer Cuivre) (net 6) (status 400))
  (segment (start 145.7706 129.1844) (end 145.415 129.54) (width 0.8636) (layer Cuivre) (net 7) (status 400))
  (segment (start 154.94 120.68048) (end 152.6794 118.41988) (width 0.8636) (layer Cuivre) (net 8) (status 400))

cp ecc83-pp.kicad_pcb zz.kicad_pcb

In zz remove the (net 2) (status 400) segment, and redraw it, and
save. Then the status flag is changed to 10.

In zz, Edit->Cleanup tracks and Vias, then save:

fgrep "(status 4" zz.kicad_pcb 
  (segment (start 159.385 117.475) (end 164.465 117.475) (width 0.8636) (layer Cuivre) (net 5) (status 420))
  (segment (start 149.86 128.905) (end 150.495 129.54) (width 0.8636) (layer Cuivre) (net 6) (status 430))
  (segment (start 151.54148 107.7722) (end 152.6794 108.91012) (width 0.8636) (layer Cuivre) (net 6) (status 420))
  (segment (start 145.7706 129.1844) (end 145.415 129.54) (width 0.8636) (layer Cuivre) (net 7) (status 430))
  (segment (start 154.94 120.68048) (end 152.6794 118.41988) (width 0.8636) (layer Cuivre) (net 8) (status 420))

I.e. they got flags IS_RESIZED and IS_NEW.


Another try:

grep segment ecc83-pp.kicad_pcb | grep status | sed -e 's/segment.*status/segment ... \(status/' | sort | uniq -c
      6   (segment ... (status 400))
     15   (segment ... (status 800))
      1   (segment ... (status C00))

# remove all status things from segments
cat ecc83-pp.kicad_pcb | sed -e 's/ (status .*)/)/' > zz.kicad_pcb

now make gerbers of the Cuivre layer (the only cu layer with tracks)
for both files and find the diff: 

diff ecc83-pp-Cuivre.gbr zz-Cuivre.gbr 
2,3c2,3
< %TF.CreationDate,2019-04-11T20:03:57+02:00*%
< %TF.ProjectId,ecc83-pp,65636338332D70702E6B696361645F70,rev?*%
---
> %TF.CreationDate,2019-04-11T20:03:27+02:00*%
> %TF.ProjectId,zz,7A7A2E6B696361645F70636200000000,rev?*%
7c7
< G04 Created by KiCad (PCBNEW 4.0.7) date Thu Apr 11 20:03:57 2019*
---
> G04 Created by KiCad (PCBNEW 4.0.7) date Thu Apr 11 20:03:27 2019*

I.e. I think we can ignore flags <= 800.


I can only find one (1) file with (status 1000000):
/Net/git/kicad/demos/complex_hierarchy/complex_hierarchy.kicad_pcb
open complex_hierarchy.kicad_pcb and Save As zz.kicad_pcb gets me a
file that only differ in the use of ".
Selecting and unselecting that specific segment, then save as, removes
the status.

I.e. I think we can ignore flags == 1000000.
