From 352ca94483a39fd6f84d591cf0474ce758f5f1b9 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sun, 6 Jun 2021 10:55:24 +0200 Subject: [PATCH] Change the way QuadTree.getLeafUnder() locate the leaf. * Change: In cumulus/plugins.Block.getLeafUnder(): formerly, we where using the cut-lines (x/y) to locate which leaf a point is under. But in case of incomplete tree, it is difficult to manage. Now we chosse the leaf according to the distance to the center of the leaf area. Choose the shorter, of course. This solve the H-Tree DFF bad assignment around the PLL (top right corner) in LS180. --- cumulus/src/plugins/alpha/block/spares.py | 46 ++++++++++++----------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/cumulus/src/plugins/alpha/block/spares.py b/cumulus/src/plugins/alpha/block/spares.py index d1f4e9d7..e0008b6e 100644 --- a/cumulus/src/plugins/alpha/block/spares.py +++ b/cumulus/src/plugins/alpha/block/spares.py @@ -345,6 +345,10 @@ class QuadTree ( object ): if self.tr: self.tr.removeUnusedBuffers() self.pool._removeUnuseds() + def getDistance ( self, point ): + """Return the Manhattan distance between ``point`` and the area center.""" + return self.area.getCenter().manhattanDistance( point ) + def rshowPoolUse ( self ): rused = 0 rtotal = 0 @@ -696,27 +700,27 @@ class QuadTree ( object ): def getLeafUnder ( self, position ): """Find the QuadTree leaf under ``position``.""" if self.isLeaf(): return self - if self.isHBipart(): - if position.getX() < self.xcut: return self.bl.getLeafUnder(position) - return self.br.getLeafUnder(position) - if self.isVBipart(): - if position.getY() < self.ycut: return self.bl.getLeafUnder(position) - return self.tl.getLeafUnder(position) - leaf = None - if position.getX() < self.xcut: - if position.getY() < self.ycut: leaf = self.bl - else: leaf = self.tl - else: - if position.getY() < self.ycut: leaf = self.br - else: leaf = self.tr - if not leaf: - dx = abs( position.getX() - self.xcut ) - dy = abs( position.getY() - self.ycut ) - if self.tr and ((dx < dy) or not leaf): leaf = self.tr - if self.tl and ((dx < dy) or not leaf): leaf = self.tl - if self.br and ((dx >= dy) or not leaf): leaf = self.br - if self.bl and ((dx >= dy) or not leaf): leaf = self.bl - return leaf.getLeafUnder(position) + candidate = None + minDist = None + if self.bl: + minDist = self.bl.getDistance( position ) + candidate = self.bl + if self.br: + distance = self.br.getDistance( position ) + if (candidate is None) or (distance < minDist): + minDist = distance + candidate = self.br + if self.tl: + distance = self.tl.getDistance( position ) + if (candidate is None) or (distance < minDist): + minDist = distance + candidate = self.tl + if self.tr: + distance = self.tr.getDistance( position ) + if (candidate is None) or (distance < minDist): + minDist = distance + candidate = self.tr + return candidate.getLeafUnder(position) def getFreeLeafUnder ( self, area, attractor=None ): """