User Tools

Site Tools



As stated in libgeda3, libgeda has some design problems that needs to be addressed. The structure described in this page is very different from the current libgeda structure and design, while hopefully can be flexible enough to be the basement of future developments.

Description of the needs in an Electrical CAD system

Schematics and PCB (or IC) designs are, by nature, a graphical representation of objects, with interconnections between them.

The basic primitives used in the graphical artwork are:

  • Lines
  • Arcs
  • Rectangles
  • Circles
  • Text
  • Images (not very often)

These basic shapes can have attributes modifying how they are drawn in the screen: dashed or dotted lines, filled or unfilled shapes,… , and can be grouped into a composed object (this object is drawn as a combination of one or more basic primitives). The graphical representation of a composed object is a symbol.

An electrical or electronic CAD must be able to draw components (composed objects) and interconnections between them. The interconnections is the key difference from other CAD packages, and are the basis of further engineering work, such as simulations or layouts. They are drawn as lines, but they are not only lines and therefore should be handled differently. The interconnection primitives are:

  • Pin or ports: points of a composed object which can be used for interconnection, or connection points between pages.
  • Nets: define the interconnections between pin or ports. It is usually drawn as a line.
  • Junction: define the connection between crossing nets. It is usually drawn as a dot at the intersection of two crossing nets.
  • Buses: group of nets. Trying to make things simple, they are drawn as a line, usually thicker than nets.
  • Bus ripper: connects a net to a bus. It is needed because there should be a way to specify which net of the bus should be connected.

An electric circuit can be drawn in a page, but, as designs grow in complexity, it is usually divided into several interconnected pages, or is drawn as a hierarchy. One common way is to draw a circuit defining some ports (where it is going to connect to other circuits), make a symbol for it, and include the symbol in other pages as it was a common composed object. So a design is composed of one or several pages, which can also include other page's symbols, and so on. Therefore, a design can be drawn as a hiearchy tree.

Finally, but not less important, every object described can have properties attached, describing the nature of the component, its attributes, or other representations (simulation models, graphical representation for PCB design,…).

Object based design

Despite its title, this is not a section talking about Object Oriented Programming. :-)

It is a known fact that all schematics are graphical representations of components, interconnections and properties, organized as a plain or hierarchical tree.

One of the current issues with libgeda is that the schematic program itself, and hence the developers, should take care of all the drawing stuff associated with schematics. Plus, there are drawing transforms, like moving, rotating, mirroring, etc… This is very time consuming for the developer, and the results are not always the best.

This was fine at the moment when it was born, but technology is continuously evolving. Today there are more advanced widgets that take care of all the object drawing, and lets the applications concentrate on what they should do. This kind of widgets are called “canvas”.

Let's take a look at one of them: goocanvas. There are no screenshots, no official webpage, but don't be scared and look further. Download it and take a look at the documentation into the “doc” directory. You can also compile a demo, but you will need GTK 2.10 (for goocanvas version greater than 0.4), or GTK2.8 (goocanvas 0.4). I can tell you that the demo of the last version (0.8 at this moment) is quite impressive. If you have time, try it!. It is worth!.

Basically what it provides is:

  • Already defined primitives: ellipse, image, path, polyline, rectangle, text, and even support for other GTK widges.
  • Takes care of all the drawing stuff.
  • Model/view implementation: several views of the same page is easily supported.
  • Full hierarchy/nesting capability: there are no nesting limits.
  • Uses cairo, already in GTK. This can be a drawback for some people, but if you have problems with cairo, it's likely you are going to have problems with the current gschem when GTK complete the transition into cairo.
  • Built-in drawing transforms (rotating, scaling, moving,…).
  • Full international text support without creating a new font. This is something true with some programs using a custom font: if you want it to support your language, you have to create the font for your special characters. (This is the case of the current gschem).
  • Built-in object visibility and clipping handling.
  • Built-in object events: it can detect clicks on objects, for example.
  • Written in C using GObject.

The advantage is clear: all the basic drawing primitives and operations are already done.

So the proposal is to base all the geda objects on the objects supplied by the canvas (note that every canvas you find is going to provide its own object classes, so this is a canvas based generic design.

geda objects

The geda object definition could be something as simple as:

struct GedaObject {
  int GedaType;
  GList *views; /* List of pointers to GooCanvasItems 
                   This could solve the problem about heterogeneus parts: 
                   We can store as many graphical representations of they object as we want */
                /* Still not sure about this, though */
  GooCanvasItem *current_view;
struct GedaObjectGroup {
  int GedaType;
  GooCanvasItem group; /* There is also an item for groups of objects */

There is no need to store graphic attributes in GedaObject. If the position is needed, since the canvas item can be queried. Some special definition for properties is needed (they shouldn't be handled as just text):

struct GedaObjectProperty {
  GooCanvasItem *name;
  GooCanvasItem *value;

and another one for connectivity items:

struct GedaObjectPort {
  int GedaType;
  GooCanvasItem *graphic;
  GedaObject *connected_object;
struct GedaObjectDotConnection {
  int GedaType;
  GooCanvasItem *graphic;
  GList *connected_objects;
struct GedaObjectNet { /* or bus, or bus ripper */
  int GedaType;
  GooCanvasItem *graphic;
  GList *connected_objects;

Everything else can be done attaching properties to the defined objects. For example, a page is just as any other GedaObject, where the view item points to a GedaObjectGroup. Notice that having multiple views for a page could be just like a page having multiple pages (at the same hierarchy level).

No object naming is required, although it is already supported by default: you can add a GedaProperty to any other object (it will become part of the object).

Example: a 7400 symbol, with a footprint attribute “DIP-16”, and reference designator “U1” would look as:

 |- views
 |    |- GedaObjectGroup 
 |    |     |- GedaObjectGroup    /* the graphic representation */
 |    |     |- GedaObjectProperty /* name = "refdes",    value="U1" */
 |    |     |- GedaObjectProperty /* name = "footprint", value="DIP-16" */
 v    v     

Integration with current code

There is no easy and direct way to get this structure into the current codebase. However, the current codebase can be adapted progressively to use this structure.

All canvas specific code can be hidden by a common interface or a runtime plugin, so a possible change of the used canvas could be easy.


Leave your comment here!

[Peter C] {

Hi. I think a canvas could be the right way to go with gschem, however we should design libgeda structures to represent the underlying circuit, design, and CAD / graphics concepts involved. I'd hope we can avoid linking any canvas or UI specific structures into libgeda. In a sense, part of what libgeda's does is define canvas independent data-structures and manipulation functions for for the graphic objects on a schematic page.

We can write a wrapper between libgeda and the canvas for actual rendering. It looks (superficially) that this is possible with goocanvas. The two basic cases are “compound” gEDA objects which map to groups of other objects (like complex objects, the current font implementation etc.), and gEDA objects which map to primitives like lines and arcs.

I think some of the important design decisions to make now involve defining the API for object / design database manipulation, and what signals and hooks we might expose to other code. I'd start by considering starting with basic “translate, rotate, mirror, ….” operations like libgeda has now, and then explore signals notifying that an object has changed.


libgeda3_object_based_design.txt · Last modified: 2012/02/20 15:14 (external edit)