This is an old revision of the document!
This page attempts to document the snapping system in pcb.
The snapping system is what takes the location of the cursor (the arrow representing the position of the mouse on the screen) and translates it into the coordinates on the board where actions take place. For example, the snapping system currently restricts the position of the crosshair to the closest grid point to the cursor. If you move the cursor near a pin or a pad, the snapping system positions the crosshair at the center of that pin or pad.
The snapping system in pcb is always active, and cannot be disabled. The snapping order… will be documented the next time I edit this page!
In pcb 4.0.2, snapping is implemented in crosshair.c, towards the end of the file. It is entirely integrated with the crosshair.
First, there is a structure that holds the information about where the crosshair is currently snapped. There is a series of functions that implement snapping.
Presently implemented in the home/cparker/snapping_overhaul branch.
The snapping code is presently located in two places: snap.[c,h] and crosshair.c. snap.[c,h] defines several general types that are used to do the snapping. crosshair.c is where the snapping actually occurs and is where all of the snapping functions are implemented.
There are three new types in snap.[c,h]:
Snapping occurs by iterating through SnapSpecType objects in a SnapListType. Each SnapSpecType object has a “search” function pointer that calls a function to look for the the object type associated with that particular SnapSpecType. These functions are presently defined in crosshair.c. So, for example, there is a SnapSpecType object associated with pins and pads called pin_pad_snap. It has a function associated with it called snap_to_pins_pads that calls SearchObjectByLocation to look for and pins or pads under the cursor, and decide if there is a valid snapping target. If there is, it passes that back to the calling function (as an object, not a pointer).
The crosshair structure has two related fields:
Presently, snapping occurs whenever the crosshair is repositioned using MoveCrosshairAbsolute (crosshair.c). This function calls Crosshair.snap(Crosshair.snaps, X, Y). If this returns non-null, we found something to snap to, and we reposition the crosshair to those coordinates.
Both of the crosshair items are implemented as pointers so that they can be changed dynamically. You could, for example, change the snap list when you go into line drawing mode so that you don't snap to elements or other lines, or do so in a different order. Similarly, you could change the snapping function to one that snaps based on which item is closest as opposed to which has the highest priority.