@@ -1316,6 +1316,100 @@ void DbNetDescriptor::findPath(NodeMap& graph,
13161316 }
13171317}
13181318
1319+ std::set<odb::Line> DbNetDescriptor::convertGuidesToLines (odb::dbNet* net) const
1320+ {
1321+ auto guides = net->getGuides ();
1322+ if (guides.empty ()) {
1323+ return {};
1324+ }
1325+
1326+ std::set<odb::Line> lines;
1327+
1328+ std::map<odb::dbTechLayer*, std::map<odb::dbObject*, std::set<odb::Rect>>>
1329+ terms;
1330+ for (odb::dbITerm* term : net->getITerms ()) {
1331+ if (!term->getInst ()->isPlaced ()) {
1332+ continue ;
1333+ }
1334+ for (const auto & [layer, itermbox] : term->getGeometries ()) {
1335+ terms[layer][term].insert (itermbox);
1336+ }
1337+ }
1338+ for (odb::dbBTerm* term : net->getBTerms ()) {
1339+ for (odb::dbBPin* pin : term->getBPins ()) {
1340+ if (!pin->getPlacementStatus ().isPlaced ()) {
1341+ continue ;
1342+ }
1343+ for (odb::dbBox* box : pin->getBoxes ()) {
1344+ terms[box->getTechLayer ()][pin].insert (box->getBox ());
1345+ }
1346+ }
1347+ }
1348+
1349+ for (const auto * guide : guides) {
1350+ const auto & box = guide->getBox ();
1351+ const auto center = box.center ();
1352+ const int width_half = box.minDXDY () / 2 ;
1353+ odb::Point p0, p1;
1354+ switch (box.getDir ()) {
1355+ case 0 : {
1356+ // DX < DY
1357+ p0 = odb::Point (center.x (), box.yMin () + width_half);
1358+ p1 = odb::Point (center.x (), box.yMax () - width_half);
1359+ break ;
1360+ }
1361+ case 1 : {
1362+ p0 = odb::Point (box.xMin () + width_half, center.y ());
1363+ p1 = odb::Point (box.xMax () - width_half, center.y ());
1364+ break ;
1365+ }
1366+ default : {
1367+ p0 = center;
1368+ p1 = center;
1369+ break ;
1370+ }
1371+ }
1372+ lines.emplace (p0, p1);
1373+
1374+ if (guide->isConnectedToTerm ()) {
1375+ std::vector<odb::Point> anchors = {p0, center, p1};
1376+
1377+ auto draw_term_connection = [&anchors, &lines](const odb::Point& term) {
1378+ // draw shortest flywire
1379+ std::stable_sort (anchors.begin (),
1380+ anchors.end (),
1381+ [&term](const odb::Point& pt0, const odb::Point& pt1) {
1382+ return odb::Point::manhattanDistance (term, pt0)
1383+ < odb::Point::manhattanDistance (term, pt1);
1384+ });
1385+ lines.emplace (term, anchors[0 ]);
1386+ };
1387+
1388+ for (const auto & [obj, objbox] : terms[guide->getLayer ()]) {
1389+ std::vector<const odb::Rect*> candidates;
1390+ for (const auto & termbox : objbox) {
1391+ if (termbox.intersects (box)) {
1392+ candidates.push_back (&termbox);
1393+ }
1394+ }
1395+ bool drawn = false ;
1396+ for (const auto * termbox : candidates) {
1397+ if (termbox->overlaps (box)) {
1398+ draw_term_connection (termbox->center ());
1399+ drawn = true ;
1400+ break ;
1401+ }
1402+ }
1403+ if (!drawn && !candidates.empty ()) {
1404+ draw_term_connection (candidates[0 ]->center ());
1405+ }
1406+ }
1407+ }
1408+ }
1409+
1410+ return lines;
1411+ }
1412+
13191413// additional_data is used define the related sink for this net
13201414// this will limit the fly-wires to just those related to that sink
13211415// if nullptr, all flywires will be drawn
@@ -1401,110 +1495,34 @@ void DbNetDescriptor::highlight(std::any object, Painter& painter) const
14011495 auto guides = net->getGuides ();
14021496 if (!guides.empty ()) {
14031497 draw_flywires = false ;
1404- painter.saveState ();
1405-
1406- Painter::Color highlight_color = painter.getPenColor ();
1407- highlight_color.a = 255 ;
1408-
1409- painter.setPen (highlight_color, true , 4 );
1410-
1411- std::map<odb::dbTechLayer*,
1412- std::map<odb::dbObject*, std::set<odb::Rect>>>
1413- terms;
1414- for (odb::dbITerm* term : net->getITerms ()) {
1415- if (!term->getInst ()->isPlaced ()) {
1416- continue ;
1417- }
1418- for (const auto & [layer, itermbox] : term->getGeometries ()) {
1419- terms[layer][term].insert (itermbox);
1420- }
1421- }
1422- for (odb::dbBTerm* term : net->getBTerms ()) {
1423- for (odb::dbBPin* pin : term->getBPins ()) {
1424- if (!pin->getPlacementStatus ().isPlaced ()) {
1425- continue ;
1426- }
1427- for (odb::dbBox* box : pin->getBoxes ()) {
1428- terms[box->getTechLayer ()][pin].insert (box->getBox ());
1429- }
1430- }
1431- }
14321498
1499+ // draw outlines of guides
14331500 std::vector<odb::Rect> guide_rects;
14341501 guide_rects.reserve (guides.size ());
14351502 for (const auto * guide : guides) {
1436- const auto & box = guide->getBox ();
1437- const auto center = box.center ();
1438- const int width_half = box.minDXDY () / 2 ;
1439- guide_rects.push_back (box);
1440- odb::Point p0, p1;
1441- switch (box.getDir ()) {
1442- case 0 : {
1443- // DX < DY
1444- p0 = odb::Point (center.x (), box.yMin () + width_half);
1445- p1 = odb::Point (center.x (), box.yMax () - width_half);
1446- break ;
1447- }
1448- case 1 : {
1449- p0 = odb::Point (box.xMin () + width_half, center.y ());
1450- p1 = odb::Point (box.xMax () - width_half, center.y ());
1451- break ;
1452- }
1453- default : {
1454- p0 = center;
1455- p1 = center;
1456- break ;
1457- }
1458- }
1459- painter.drawLine (p0, p1);
1460-
1461- if (guide->isConnectedToTerm ()) {
1462- std::vector<odb::Point> anchors = {p0, center, p1};
1463-
1464- auto draw_term_connection
1465- = [&anchors, &painter](const odb::Point& term) {
1466- // draw shortest flywire
1467- std::stable_sort (
1468- anchors.begin (),
1469- anchors.end (),
1470- [&term](const odb::Point& pt0, const odb::Point& pt1) {
1471- return odb::Point::manhattanDistance (term, pt0)
1472- < odb::Point::manhattanDistance (term, pt1);
1473- });
1474- painter.drawLine (term, anchors[0 ]);
1475- };
1476-
1477- for (const auto & [obj, objbox] : terms[guide->getLayer ()]) {
1478- std::vector<const odb::Rect*> candidates;
1479- for (const auto & termbox : objbox) {
1480- if (termbox.intersects (box)) {
1481- candidates.push_back (&termbox);
1482- }
1483- }
1484- bool drawn = false ;
1485- for (const auto * termbox : candidates) {
1486- if (termbox->overlaps (box)) {
1487- draw_term_connection (termbox->center ());
1488- drawn = true ;
1489- break ;
1490- }
1491- }
1492- if (!drawn && !candidates.empty ()) {
1493- draw_term_connection (candidates[0 ]->center ());
1494- }
1495- }
1496- }
1503+ guide_rects.push_back (guide->getBox ());
14971504 }
1498-
1499- painter.restoreState ();
1500-
1501- // draw outlines of guides
15021505 painter.saveState ();
15031506 painter.setBrush (painter.getPenColor (), gui::Painter::Brush::kNone );
15041507 for (const odb::Polygon& outline : odb::Polygon::merge (guide_rects)) {
15051508 painter.drawPolygon (outline);
15061509 }
15071510 painter.restoreState ();
1511+
1512+ painter.saveState ();
1513+ Painter::Color highlight_color = painter.getPenColor ();
1514+ highlight_color.a = 255 ;
1515+ painter.setPen (highlight_color, true , 4 );
1516+
1517+ std::set<odb::Line> lines = convertGuidesToLines (net);
1518+ if (sink_object != nullptr ) {
1519+ } else {
1520+ for (const auto & line : lines) {
1521+ painter.drawLine (line);
1522+ }
1523+ }
1524+
1525+ painter.restoreState ();
15081526 }
15091527 }
15101528 }
0 commit comments