pcb-rnd knowledge pool
Why there is no negative copper layer
negcopper by Tibor 'Igor2' Palinkas on 2018-09-21
Tags: insight, negative, drawn, copper, layer, clearance, polygon, erase
Abstract: Explain with simple examples why negative-drawn copper is not supported.
Pcb-rnd has composite layer groups for most layers, which means layers can be set to drawn positively or negatively. Negative draw means 'erase'. This works for any layer, except copper layers.
The reason for the difference is the famous "find.c" in the source, and more specifically the functionality it implements. On copper layers, pcb-rnd needs to be able to map galvanic connections. That is done by calculating whether specific objects intersect with other objects. Calculating the intersection is not as easy as it first sounds: objects have real complex geometry. Even a simple line is complex: it is a round end cap line, which means two half-circles and a rectangle in between. To decide if two lines intersect, it is not enough to consider if their centerlines intersect - it well may be that the end cap circles (extending beyond the centerline's endpoint!) touch.
The connection finding is called very frequently from the rats nest code and the DRC code. It must be very fast, else it slows down the most common daily use cases - slows down pcb-rnd in general.
Being fast is done by having special code paths for all the common cases. Pcb-rnd doesn't have too many object types: arc, line, text, polygon, padstack and subcircuit. A subcircuit doesn't have its own geometry, so find.c needs to deal only with the other 5 in the intersection code. And it does have a specific, highly optimized functions for line-line, line-arc, arc-arc, line-polygon, arc-polygon, polygon-polygon, etc. intersections calculations.
If pcb-rnd supported negatively drawn copper, it would be easy to construct objects with special properties that the above code can not handle. For example a simple straight line segment could be cut with a slanted line or the round 'clearance' of a via:
The resulting line has round cap on the other end, but some real strange, generic, complex, shape on the other end. This means the efficient line intersection code can not be used, because it works only with round end cap. It is impossible to code efficient special case intersection code for these lines, because the cut end can be literally any shape.
But pcb-rnd indeed does have an any-shape intersection code too: the polygon code! This means, in theory, the broken line could be converted into a polygon for the tests. This would work in theory, but would fail in practice:
- the code would need to decide which objects are affected; this is very hard to implement for the same reason as we can't calculate efficient intersections with random erases
- so the code would end up doing this instead: if a copper layer group has any negatively drawn layer, every object on that layer is converted to polygon before the intersection tests
- which means a few thousand polygons on a layer; would work, but would be extremely slow
This is also related to clearances : a clearance happens only within a polygon. A polygon is already a polygon, so there's no conversion and it is not slowing down the system much more. This is the reason why clearances do not clear from anything else by polygons.
(Note: having clearances in polygons does slow down pcb-rnd a bit; the more clearance, the more complex shaped edge, the more slowdown.)
Another interesting special case is thermals: they happen around terminals, typically around padstacks. As of pcb-rnd 2.0.x series, they are typically constructed as a few round cap objects subtracted from the sorrunding polygons, leaving small bridges intact. This also works only against polygons: a padstack via placed within a real thick line will never have a thermal cut out from the line.