www.delorie.com/archives/browse.cgi   search  
Mail Archives: geda-user/2016/01/22/00:58:48

X-Authentication-Warning: delorie.com: mail set sender to geda-user-bounces using -f
X-Recipient: geda-user AT delorie DOT com
Message-ID: <56A1C4AE.9010703@xs4all.nl>
Date: Fri, 22 Jan 2016 06:57:02 +0100
From: "Bert Timmerman (bert DOT timmerman AT xs4all DOT nl) [via geda-user AT delorie DOT com]" <geda-user AT delorie DOT com>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.19) Gecko/20110429 Fedora/2.0.14-1.fc13 SeaMonkey/2.0.14
MIME-Version: 1.0
To: geda-user AT delorie DOT com
Subject: Re: [geda-user] PCB data structures
References: <1512221837 DOT AA25291 AT ivan DOT Harhan DOT ORG> <20160106133049 DOT 5A0E9809D79B AT turkos DOT aspodata DOT se> <CACwWb3Cyk4yLwt3=V1Mu5C4RieOQEjYH3ej5MXZSNnLPbshqDg AT mail DOT gmail DOT com> <20160106143629 DOT 4D39D809D79B AT turkos DOT aspodata DOT se> <CACwWb3BXbnQXs+DwVVzmC8DrhwOYxPgVyUhZTPL9bM9cJbHimw AT mail DOT gmail DOT com> <20160106164022 DOT D0D4E809D79B AT turkos DOT aspodata DOT se> <20160106180912 DOT 42ddf4079d91384f206b7c35 AT gmail DOT com> <20160106191433 DOT 5dc5cb59 AT jive DOT levalinux DOT org> <20160106202817 DOT 56197b2c539d426a1b724c9e AT gmail DOT com> <568E09ED DOT 1080508 AT m0n5t3r DOT info> <CACwWb3AhSh-+NNu--bVMGZBfjaoA+hHg7gbXnoyNv3oMq=e17g AT mail DOT gmail DOT com> <568E6354 DOT 80302 AT m0n5t3r DOT info> <20160108002640 DOT 03233b24 AT jive DOT levalinux DOT org> <20160108175259 DOT 127a3f073616758434f7edff AT gmail DOT com> <20160109020345 DOT 1e07cb84 AT jive> <CAC4O8c-nqs2+9rgsD-Gsks-wSmJ1eCkJ9PFMi3XqMrYE2FO3Ew AT mail DOT gmail DOT com> <20160109112851 DOT 1129dc38 AT wind DOT levalinux DOT org> <CAC4O8c_tFOOXCA5ABEMuSU8BnXMZWauV+uJYy-TJO7nJYBS9+A AT mail DOT gmail DOT com> <alpine DOT DEB DOT 2 DOT 11 DOT 1601111649470 DOT 5421 AT nimbus>
In-Reply-To: <alpine.DEB.2.11.1601111649470.5421@nimbus>
Reply-To: geda-user AT delorie DOT com

Roland Lutz wrote:
> On Sat, 9 Jan 2016, Britton Kerin (britton DOT kerin AT gmail DOT com) [via 
> geda-user AT delorie DOT com] wrote:
>> First the existing parser needs to get separated from the innards of 
>> pcb.
>
> I agree.
>
>> As things stand now there's no single data structure that corresponds
>> one-to-one with the format.  Once this is done other equivalent formats
>> could be implemented.
>
> So let's start with that! :-)  I translated the PCB file format 
> definition into a set of C structs which you find below.  The 
> rationale behind this data structures is as follows:
>
> - An "object" should be something that is located at some position on 
> the board, and which makes sense to manipulate as an entity (e.g., 
> both an "element instance" and a "pad" are objects, but an attribute 
> is not).
>
> - The location of an object in the hierarchy should be independent 
> from the actual data which makes up the object (i.e., there are no 
> pointers to child objects in the data structures; the hierarchy is 
> managed separately and points to each object's data).
>
> - The data structure should be semantic; any value should have an 
> explicit field, explicit type, and explicit meaning.  Attributes are 
> implemented as fields in a struct so they are semantically accessible 
> to other users of the data structure.
>
> - All code operating on these data structures should be in the main 
> repository, so if some change to the data structure is necessary, it 
> can be performed without having to worry about breaking code elsewhere.
>
> - The data structure should not contain any fields that are internal 
> to the PCB implementation.
>
> How the in-memory object hierarchy should look like is actually a 
> non-trivial question.  I think it's generally a good idea to have the 
> state of the object tree represent something on which you can do a 
> meaningful undo/redo: for schematics, for example, this would be each 
> referenced or embedded symbol, and the schematic itself.  But a PCB 
> file consists of four different kinds of things: the PCB layout, the 
> imported netlist, the elements in the layout, and the stroke font.
>
> The netlist is a bit different in that it doesn't have a geometric 
> structure; it's not "objects" in the definition above.  The stroke 
> font symbols are obvious candidates for separate object trees.  The 
> hard question is whether to treat an element as a "group object" which 
> contains a bunch of element line/arc, pin, and pad objects, or to 
> treat it as an instantiation of an embedded element definition (a.k.a. 
> footprint).
>
> I think from a logical perspective it makes more sense to treat it as 
> an instantiation (you might want to update an embedded footprint, or 
> to not embed but reference a footprint in the future), but the way 
> elements are currently used suggests a group object notion, too (for 
> example changing the sizes of individual pads/pins in an existing 
> element).  Since I had to choose, I finally went with treating them as 
> an instantiation (this is at least consistent with the way we treat 
> symbols in gEDA/gaf).
>
>
> ### Object hierarchy ###
>
> A PCB file contains a PCB layout, an arbitrary number of footprints, 
> and (usually) 94 symbols.
>
> The PCB layout has an object of type pcb_layout as the root object, 
> which can contain an arbitrary number of pcb_layer objects--which in 
> turn contain the geometric primitives--and pcb_element objects which 
> aren't associated with a layer.  Objects of type pcb_polygon can have 
> child objects of type pcb_polygon_hole:
>
> pcb_layout
> +- pcb_layer
>    +- pcb_arc
>    +- pcb_line
>    +- pcb_pad
>    +- pcb_pin
>    +- pcb_polygon
>       +- pcb_polygon_hole
>    +- pcb_rat
>    +- pcb_text
>    +- pcb_via
> +- pcb_element
>
> A footprint (element definition) has a pcb_footprint object as the 
> root object which can only contain objects of the types 
> pcb_element_arc, pcb_element_line, pcb_pad, and pcb_pin:
>
> pcb_footprint
> +- pcb_element_arc
> +- pcb_element_line
> +- pcb_pad
> +- pcb_pin
>
> A symbol definition has a pcb_symbol object as the root object which 
> can contain pcb_symbol_line objects:
>
> pcb_symbol
> +- pcb_symbol_line
>
>
> ### Struct definitions ###
>
> I'm using double coordinates here.  This is not a meant as a statement 
> regarding integer vs. floating-point values; you can simply replace 
> "double" with your favorite kind of "int".
>
> The "flags" field gave me a bit of trouble since it is a kind of 
> general-purpose field which contains a lot of unrelated information. 
> Most of this is only valid for certain object types, though, so I 
> moved these flags to the appropriate type structs.  What remained is 
> five flags which apply to most geometric objects:
>
> /* Helper struct
>    used by arc, line, pad, pin, rat, text, via, element, and element 
> text */
>
> struct pcb_flags {
>     bool found;
>     bool selected;
>     bool failed_drc;
>     bool locked;
>     bool connected;
> };
>
> It may make sense to move some of this information (found and selected 
> objects, DRC result) to a different place later since it represents a 
> set of objects, not a state of an individual object.
>
> There are some directives (Grid, PolyArea, Thermal, DRC, Styles) which 
> relate to the PCB file as a whole and can't be used more than once, so 
> I grouped them into the pcb_layout data structure:
>
> struct pcb_layout {
>     struct string name;
>     struct double2d size;
>     struct {
>         double step;
>         struct double2d offset;
>         bool visible;
>     } grid;
>     struct {
>         double area;
>     } poly_area;
>     struct {
>         double scale;
>     } thermal;
>     struct {
>         double bloat;
>         double shrink;
>         double line;
>         double silk;
>         double drill;
>         double ring;
>     } drc;
>     struct {
>         bool showdrc;
>         bool rubberband;
>         bool nameonpcb;
>         bool autodrc;
>         /* ... flags ... */
>     } flags;
>     struct string groups;
>     struct {
>         struct string name;
>         double thickness;
>         double diameter;
>         double drill;
>         double keepaway;
>     } styles[4];
>     struct {
>         bool grid_imperial;
>         double grid_size;
>         /* ... attributes ... */
>     } attributes;
> };
>
> I probably missed some flags and attributes because I couldn't find a 
> list in the documentation and guessed from an example file.
>
> There isn't much data associated with a layer, just the number and a 
> name:
>
> struct pcb_layer {
>     int number;
>     struct string name;
> };
>
> The geometric objects contain a "flags" field (except for 
> pcb_polygon). Some flags which are only valid for certain object types 
> are defined directly in the object's data structure, and pcb_element 
> contains two sets of flags, one for the element itself and one for its 
> text label:
>
> struct pcb_arc {
>     struct double2d pos;
>     struct double2d radius;
>     double thickness;
>     double clearance;
>     int startangle;
>     int deltaangle;
>     bool clear_polygons;
>     struct pcb_flags flags;
> };
>
> struct pcb_element {
>     struct pcb_flags flags;
>     struct string desc;
>     struct string name;
>     struct string value;
>     struct double2d mark;
>     struct double2d text;
>     int tdir;
>     double tscale;
>     bool hide_element_name;
>     bool show_pin_names;
>     bool onsolder;
>     struct pcb_flags tflags;
>     struct pointer footprint;
> };
>
> struct pcb_line {
>     struct double2d pos[2];
>     double thickness;
>     double clearance;
>     bool clear_polygons;
>     bool autorouted;
>     struct pcb_flags flags;
> };
>
> struct pcb_pad {
>     struct double2d pos[2];
>     double thickness;
>     double clearance;
>     double mask;
>     struct string name;
>     struct string number;
>     bool nopaste;
>     bool onsolder;
>     bool square;
>     bool warn;
>     bool edge2;
>     struct pcb_flags flags;
> };
>
> struct pcb_pin {
>     struct double2d pos;
>     double thickness;
>     double clearance;
>     double mask;
>     double drill;
>     struct string name;
>     struct string number;
>     bool hole;
>     bool square;
>     bool warn;
>     bool octagon;
>     bool edge2;
>     struct pcb_flags flags;
> };
>
> struct pcb_polygon {
>     struct double2d_list vertices;
>     bool clear;
>     bool full;
> };
>
> struct pcb_polygon_hole {
>     struct double2d_list vertices;
> };
>
> struct pcb_rat {
>     struct double2d pos[2];
>     int group[2];
>     struct pcb_flags flags;
> };
>
> struct pcb_text {
>     struct double2d pos;
>     int direction;
>     double scale;
>     struct string string;
>     struct pcb_flags flags;
> };
>
> struct pcb_via {
>     struct double2d pos;
>     double thickness;
>     double clearance;
>     double mask;
>     double drill;
>     struct string name;
>     bool hole;
>     bool autorouted;
>     bool warn;
>     bool octagon;
>     struct pcb_flags flags;
> };
>
> The pcb_footprint structure has much duplication with pcb_element.  
> Some of this can probably be removed since some fields only make sense 
> for an element instance and others for a footprint, but since I'm not 
> too familiar with the way PCB works, I thought it would be safer to 
> keep them for now:
>
> struct pcb_footprint {
>     struct string desc;
>     struct string name;
>     struct string value;
>     struct double2d mark;
>     struct double2d text;
>     int tdir;
>     double tscale;
>     bool hide_element_name;
>     bool show_pin_names;
>     bool onsolder;
>     struct {
>         struct string device;
>         struct string manufacturer;
>         struct string manufacturer_part_number;
>         struct string vendor;
>         struct string vendor_part_number;
>         /* ... attributes ... */
>     } attributes;
> };
>
> As with the PCB file, I guessed the attributes from an example file 
> and probably missed some.
>
> struct pcb_element_arc {
>     struct double2d pos;
>     struct double2d radius;
>     int startangle;
>     int deltaangle;
>     double thickness;
> };
>
> struct pcb_element_line {
>     struct double2d pos[2];
>     double thickness;
> };
>
> Finally, symbol definitions:
>
> struct pcb_symbol {
>     wchar_t ch;
>     double delta;
> };
>
> struct pcb_symbol_line {
>     struct double2d pos[2];
>     double thickness;
> };
Hi,

AFAICT a via lives on board level.

All the via_pads beloging to a via have all the same 
location/dimensions/connectivity and are switched on/off per layer level 
inside the via definition.

Kind regards,

Bert Timmerman.

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019