Mail Archives: geda-user/2016/01/22/00:58:48
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 -