Table of Contents

Overview

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:

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:

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:

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 {
  GedaType;
  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:

GedaObject
 |- 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.

Comments?

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.

}