BusWireSeparate Module
Functions and values
| Function or value | Description |
Full Usage:
adjustSegmentsInModel ori model lines
Parameters:
Orientation
model : Model
lines : Line list
Returns: bool * Model
|
|
Full Usage:
alignSameNetDepartures wiresToRoute model
Parameters:
ConnectionId list
model : Model
Returns: Model
|
Where two wires of a net run along a shared trunk and turn off it at different points, move one
turn onto the other so the net leaves the trunk once, as a T junction. The reader sees one
branch instead of two near-parallel ones, and the drawing is strictly shorter - the move is
only made when it is.
The candidate moved is a wire's interior perpendicular segment (the "riser"): its base slides
along the trunk to the other riser's position, its two neighbours stretching and shrinking to
pay for it, exactly as a segment drag would. Guards, in order:
- neither wire is routed by hand, and the riser's neighbours are interior and keep their
directions (a neighbour driven past zero would fold the wire back over itself);
- the riser at its new position stays at least minWireSeparation clear of every
same-orientation segment of any OTHER net it would run beside - the one thing separation
cannot repair afterwards, since no later pass runs;
- it also stays clear of every symbol: the merged riser can reach further along its axis than
the riser it joins, into space nothing has checked.
Of the two ways round (move A to B, move B to A) the one leaving less visible wire wins, and a
move is only made when the net's drawn length strictly falls - which is also what guarantees
the repeated scan terminates.
|
|
|
|
Function which given a cluster (loc) works out how to spread out the contained segments optimally, spacing them from other segments and symbols. Return value is a list of segments, represented as Lines, paired with where they move. lines is the source list of lines (vertical or horizontal according to which is being processed). model is the Buswire model needed to access wires. |
Full Usage:
checkExtensionNoCrossings overlap ext excludedWire info
Parameters:
float
ext : Extension
excludedWire : ConnectionId
info : LineInfo
Returns: bool
|
|
Full Usage:
checkExtensionNoOverlap overlap ext excludedWire info
Parameters:
float
ext : Extension
excludedWire : ConnectionId
info : LineInfo
Returns: bool
|
|
Full Usage:
expandCluster index searchDir lines
Parameters:
int
searchDir : LocSearchDir
lines : Line array
Returns: Cluster
|
|
|
Return the index of the Line with the smallest value of P > p Use binary earch for speed. The search narrows towards `lines[below].P < p <= lines[above].P`, so the bottom end has to be checked before it starts: with below = 0 taken on trust, an array whose first line is already at or above p returns 1 and the caller never looks at line 0. If every line is below p the last index is returned, which callers detect for themselves.
|
|
|
Full Usage:
isSegmentExtensionOk info wire segNum ori startShift newLength
Parameters:
LineInfo
wire : Wire
segNum : int
ori : Orientation
startShift : float
newLength : float
Returns: bool
|
Return true if the given segment length change is allowed. If the new segment creates a part line segment that did not previouly exist this is checked for overlap with symbols and other wires. startShift is how far the start of the segment itself moves along its own axis: zero when the segment keeps its start point, negative when it is extended backwards (as the second segment of a removed corner is, since the segment before it has gone).
|
|
|
|
|
|
Where two segments in lines are on the same Net and on top of each other we must NEVER separate them. This function links such segments, and marks all except the head one as a LINKEDSEG so that the clustering algorithm will ignore them. sameNetCapture specified how close segments muts be to be linked.
|
|
Scan through segments in P order creating a list of local Clusters. Within one cluster segments are adjacent and overlapping. Note that different clusters may occupy the same P values if their segments do not overlap. Segments within each cluster will be repositioned and reordered after clusters are identified. Every segment must be part of a unique cluster.
|
Full Usage:
makeLineInfo wiresToRoute model
Parameters:
ConnectionId list
model : Model
Returns: LineInfo
|
Process the symbols and wires in Model generating arrays of Horizontal and Vertical lines. In addition the inverse map is generated which can map each segmnet to the corresponding Line if that exists. Note that Lines reference segments, which contain wire Id and segment Index and can therefore be used to reference the corresponding wire via the model.Wires map.
|
Full Usage:
makeLines wiresToRoute ori model
Parameters:
ConnectionId list
ori : Orientation
model : Model
Returns: Line array
|
|
|
|
|
|
|
|
|
|
|
Take the routing off the wires `toRedraw` selects, route them all again from nothing, and then separate the whole sheet as usual. Neither pass is changed: this is the ordinary pair of them, applied to many wires at once instead of to the few a drag reaches. That is what makes it worth having - a sheet laid out before a routing change keeps most of its old routing, and so says almost nothing about whether the change helped. The routing comes off every one of them BEFORE any of them is routed. Routing looks only at symbols today, so that makes no difference yet; it will as soon as a wire is routed with any regard for the wires already there, since a route which is about to be thrown away is not something the next wire should be following. Wires are reset rather than deleted and recreated: a wire is identified by the two ports it joins, so deleting one would only lose its ConnectionId, which the saved file, undo and the current selection all refer to. They are routed shortest first, by the straight-line distance between the two ports. Order is immaterial while routing considers only symbols, and this is the order to have when it stops being: a short wire has the least freedom in where it can go, so it is the one that should already be there when a longer wire of the same net is routed and looking for something to join. The re-route this replaces went in Map order - by ConnectionId, which is a GUID, so in no order at all and not the same one twice.
|
|
|
Full Usage:
removeModelCorners wires model
Parameters:
ConnectionId list
model : Model
Returns: Model
|
|
|
|
|
|
Full Usage:
routeAndSeparateSymbolWires model compId
Parameters:
Model
compId : ComponentId
Returns: Model
|
Route and then separate after one symbol has changed - moved a step, rotated, scaled, flipped or had its type edited. Uses partial routing to keep the symbol's hand-routed wires attached - a changed port position must reach them, and the redraw below deliberately leaves manual wires alone. A wire with both ends on the symbol is re-routed from each end in turn rather than translated, since the symbol may have been resized or rotated, not just moved. It ends as a drag does: every floating wire re-routed from scratch and the whole sheet separated. A wire that had been ROUTED AROUND this symbol is not connected to it, so no re-route of the symbol's own wires reaches it, and its detour is routing's - separation cannot undo it. The layout left behind is exactly what "redraw floating wires" would produce, so a symbol change leaves nothing for a redraw to improve.
|
Full Usage:
segmentToLine lType ori wire seg
Parameters:
LType
ori : Orientation
wire : Wire
seg : ASegment
Returns: Line
|
|
Full Usage:
separateAndOrderModelSegments wiresToRoute model
Parameters:
ConnectionId list
model : Model
Returns: Model
|
Perform complete wire segment separation and ordering for all orientations. `wiresToRoute` is the SCOPE: only clusters holding one of these wires are touched, so a small list is a local adjustment and every wire id is a whole-sheet pass. Which to use follows from what changed. Adding one wire, or dragging a segment of one, disturbs only the clusters that wire runs through - the rest of the sheet was settled a moment ago and owes nothing to this change. Moving a SYMBOL is different: its wires may leave clusters anywhere on the sheet, and the space they vacate is space other wires should take up, so a drag's mouse-up passes every wire (see the MovingSymbols cases in SheetUpdateHelpers, and routeAndSeparateSymbolWires). An empty list means nothing changed, and the whole pass is skipped.
|
Full Usage:
separateFixedSegments wiresToRoute ori model
Parameters:
ConnectionId list
ori : Orientation
model : Model
Returns: Model
|
Segments which could be moved, but would make an extra segment if moved, are marked Fixed and not moved by the normal cluster-based separation functions. This function looks at these segments and moves them a little in the special case that they overlap. It is called after the main segment separation is complete.
|
Full Usage:
separateModelSegmentsOneOrientation wiresToRoute ori model
Parameters:
ConnectionId list
ori : Orientation
model : Model
Returns: bool * Model
|
Perform complete segment ordering and separation for segments of given orientation. wiresToRoute: the clusters worked on are those holding at least one of these wires. Lines are generated for ALL wires either way - a cluster is defined by everything near it - and passing every wire id makes this a whole-sheet pass.
|
Full Usage:
turnDirs line wires
Parameters:
Line
wires : Map<ConnectionId, Wire>
Returns: int * int
|
|
Full Usage:
turnLengths line wires
Parameters:
Line
wires : Map<ConnectionId, Wire>
Returns: float * float
|
|
Full Usage:
updateWireSegmentJumpsAndSeparations wires model
Parameters:
ConnectionId list
model : Model
Returns: Model
|
|
|
Report the rare case of a segment getting "orphaned" - left out of every cluster. This should probably never happen, and should be fixed if it is ever seen. Once per key, not once per occurrence: this is reached from the separation scan, which runs on every symbol move, so an unconditional complaint here would arrive at drag rate. |
|
How bad a wiring is: the length of wire actually drawn, plus a heavy penalty for two different nets drawn on top of each other. Wire drawn is the length of the UNION of the segments on each line of the drawing, so two segments of one net lying on top of each other are one wire and are counted once. That makes "keep wires short" and "let a net share a trunk" the same objective rather than two which have to be traded off by hand. This is called once per settling round, so it is one sort and one sweep. Deliberately not built on makeLines, which links same-net lines pairwise and costs as much as a separation pass.
|