| 66 | } |
| 67 | |
| 68 | NetSegmentSimplifier::Result NetSegmentSimplifier::simplify() noexcept { |
| 69 | // Clear state. |
| 70 | mAnchorMap.clear(); |
| 71 | mPinsOrPads.clear(); |
| 72 | mNextFreeLineId = mLines.count(); |
| 73 | mModified = false; |
| 74 | |
| 75 | // First, group all anchors by position. |
| 76 | // Important: Fixed anchors (pads & vias) must appear first, and non-fixed |
| 77 | // anchors (junctions) last! Thus we sort the anchors by type. |
| 78 | for (const Anchor& anchor : std::as_const(mAnchors)) { |
| 79 | mAnchorMap[anchor.pos].append(anchor); |
| 80 | } |
| 81 | for (auto it = mAnchorMap.begin(); it != mAnchorMap.end(); it++) { |
| 82 | std::sort(it->begin(), it->end(), [](const Anchor& a, const Anchor& b) { |
| 83 | return static_cast<int>(a.type) < static_cast<int>(b.type); |
| 84 | }); |
| 85 | } |
| 86 | |
| 87 | // Get all IDs of pins or pads. |
| 88 | for (const Anchor& anchor : std::as_const(mAnchors)) { |
| 89 | if (anchor.type == AnchorType::Fixed) { |
| 90 | mPinsOrPads.insert(anchor.id); |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | // Memorize which pins or pads are currently connected. |
| 95 | const QSet<int> connectedFixedAnchors = getConnectedFixedAnchors(); |
| 96 | |
| 97 | // Add junctions where lines are intersecting each other. Those lines will |
| 98 | // then be split in the next step to connect with the new anchors. |
| 99 | addJunctionsAtLineIntersections(); |
| 100 | |
| 101 | // Split netlines by junctions intersecting them. |
| 102 | splitLinesAtAnchors(); |
| 103 | |
| 104 | // Replace unnecessary junctions by the first suitable anchor from the |
| 105 | // anchors map. Pads and vias will have priority, junctions are only |
| 106 | // used if they are not redundant with any pad or via. Redundant junctions |
| 107 | // will not be used anymore (they appear multiple times in the anchors map, |
| 108 | // but we will use only the first of them). |
| 109 | removeDuplicateJunctions(); |
| 110 | |
| 111 | // Remove redundant lines. If there are redundant lines with different |
| 112 | // widths, keep the thickest of them. |
| 113 | removeRedundantLines(); |
| 114 | |
| 115 | // Remove unnecessary junctions in the middle of straight lines. |
| 116 | // This needs to be done in a loop (trace by trace) until no more lines |
| 117 | // can be merged. |
| 118 | while (mergeNextLines()) { |
| 119 | mModified = true; |
| 120 | } |
| 121 | |
| 122 | Result result{ |
| 123 | mLines.values(), |
| 124 | {}, |
| 125 | connectedFixedAnchors - getConnectedFixedAnchors(), |