void CornerSequence::setMacrosPositionByCorners() { for (int i = 0; i < macros->size(); ++i) { Macro *macro = macros->at(i); macro->setOrientation(orientations->at(i)); Corner *corner = corners->at(i); switch (corner->getDirection()) { case 0: macro->setXStart(corner->getX()); macro->setYStart(corner->getY()); break; case 1: macro->setXEnd(corner->getX()); macro->setYStart(corner->getY()); break; case 2: macro->setXStart(corner->getX()); macro->setYEnd(corner->getY()); break; case 3: macro->setXEnd(corner->getX()); macro->setYEnd(corner->getY()); break; } macro->updateRectanglesPosition(); } }
bool CornerSequence::placeMacrosWithIncrementalUpdate(int startPosition, int backupPosition) { bool placedUnsuccessfully = false; // Store Corners removed from sizeQuadtree during finding valid Corners. std::vector<Corner *> *temporarilyRemovedCorners = new std::vector<Corner *>(); for (int i = startPosition; i < macros->size(); ++i) { //std::cout << i << "\n"; Macro *macro = macros->at(i); macro->setOrientation(orientations->at(i)); int macroWidth = macro->getWidth(); int macroHeight = macro->getHeight(); Corner *corner = corners->at(i); //std::cout << "begin Macro " << i << "\n"; //std::cout << "smallest width emtpy Tile: "; //cornerHorizontalTilePlane->getEmptyTileWithSmallestWidth()->print(); //std::cout << "smallest height empty Tile: "; //cornerVerticalTilePlane->getEmptyTileWithSmallestHeight()->print(); //std::cout << "smallest width Macro: "; //////(*widthSortedMacros->begin())->print(); //widthSortedMacros->getSmallest()->print(); //std::cout << "smallest height Macro: "; ////(*heightSortedMacros->begin())->print(); //heightSortedMacros->getSmallest()->print(); //fillInWastedRegion(); // Check whether to select another Corner. bool toSelectAnotherCorner = false; if (corner == 0) { toSelectAnotherCorner = true; } else if (corner->isNotFromTilePlane()) { Corner *inputCorner = corner; std::vector<Point *> *foundCorners = positionQuadtree->getPointsAtXY(inputCorner->getX(), inputCorner->getY()); if (foundCorners == 0) { // No matched Corner is found. toSelectAnotherCorner = true; } else { for (int j = 0; j < foundCorners->size(); ++j) { Corner *foundCorner = static_cast<Corner *>(foundCorners->at(j)); if (foundCorner->getDirection() == inputCorner->getDirection()) { // The matched Corner is found. corner = foundCorner; break; } // No matched Corner is found. toSelectAnotherCorner = true; } delete foundCorners; } delete inputCorner; corners->at(i) = 0; // If macro ends up being unsuccessfully placed, // notFromTilePlane Corners after corner will be deleted in ~CornerSeqence(). } if (toSelectAnotherCorner) { corner = static_cast<Corner *>(sizeQuadtree->getPointRandomlyByXY(macroWidth, macroHeight, true, true)); if (corner == 0) { // No Corner is available. placedUnsuccessfully = true; indexPlacedUnsuccessfully = i; break; } } // Check overlap. int cornerDirection; int macroXStart; int macroYStart; int macroXEnd; int macroYEnd; int cornerX; int cornerY; while (true) { // Check corner gap size. bool cornerGapSizeIsValid = true; if (corner->isType1()) { if (corner->isGapOnHorizontalSide()) { if (corner->getGapSize() >= macroWidth) { cornerGapSizeIsValid = false; } } else { if (corner->getGapSize() >= macroHeight) { cornerGapSizeIsValid = false; } } } if (cornerGapSizeIsValid) { // Calculate macro position. cornerX = corner->getX(); cornerY = corner->getY(); cornerDirection = corner->getDirection(); switch (cornerDirection) { case 0: // Bl macroXStart = cornerX; macroYStart = cornerY; macroXEnd = cornerX + macroWidth; macroYEnd = cornerY + macroHeight; break; case 1: // Br macroXStart = cornerX - macroWidth; macroYStart = cornerY; macroXEnd = cornerX; macroYEnd = cornerY + macroHeight; break; case 2: // Tl macroXStart = cornerX; macroYStart = cornerY - macroHeight; macroXEnd = cornerX + macroWidth; macroYEnd = cornerY; break; case 3: // Tr macroXStart = cornerX - macroWidth; macroYStart = cornerY - macroHeight; macroXEnd = cornerX; macroYEnd = cornerY; break; } // Check overlap. if (cornerDirection <= 1) { if (cornerHorizontalTilePlane->checkAreaEmptyCheckFromBottom( macroXStart, macroYStart, macroXEnd, macroYEnd, corner->getHorizontalTile())) { // Does not overlap. break; } } else { if (cornerHorizontalTilePlane->checkAreaEmptyCheckFromTop( macroXStart, macroYStart, macroXEnd, macroYEnd, corner->getHorizontalTile())) { // Does not overlap. break; } } } // corner is not valid. // Select another Corner. sizeQuadtree->remove(corner); temporarilyRemovedCorners->push_back(corner); corner = static_cast<Corner *>(sizeQuadtree->getPointRandomlyByXY(macroWidth, macroHeight, true, true)); if (corner == 0) { // No Corner is available. placedUnsuccessfully = true; indexPlacedUnsuccessfully = i; break; } } if (placedUnsuccessfully) { break; } // A valid Corner is selected. // Insert removed Corners back to quadtrees. for (int j = 0; j < temporarilyRemovedCorners->size(); ++j) { sizeQuadtree->insert(temporarilyRemovedCorners->at(j)); } temporarilyRemovedCorners->clear(); // Copy the valid Corner and replace corners->at(i) // because the valid Corner will be deleted after macro is placed. corners->at(i) = corner->copyAsNotFromTilePlane(); // Place macro at corner. macro->setXStart(macroXStart); macro->setYStart(macroYStart); macro->updateRectanglesPosition(); Tile *horizontalTile = new Tile(macroXStart, macroYStart, macroXEnd, macroYEnd, true); Tile *verticalTile = new Tile(macroXStart, macroYStart, macroXEnd, macroYEnd, true); Tile *startHorizontalTile; Tile *startVerticalTile; switch (cornerDirection) { case 0: // Bl startHorizontalTile = corner->getHorizontalTile(); startVerticalTile = corner->getVerticalTile(); break; case 1: // Br startHorizontalTile = corner->getHorizontalTile(); startVerticalTile = cornerVerticalTilePlane->findTile(macroXStart, macroYStart, corner->getVerticalTile()); break; case 2: // Tl startHorizontalTile = cornerHorizontalTilePlane->findTile(macroXStart, macroYStart, corner->getHorizontalTile()); startVerticalTile = corner->getVerticalTile(); break; case 3: // Tr startHorizontalTile = cornerHorizontalTilePlane->findTile(macroXStart, macroYStart, corner->getHorizontalTile()); startVerticalTile = cornerVerticalTilePlane->findTile(macroXStart, macroYStart, corner->getVerticalTile()); break; } cornerHorizontalTilePlane->placeSolidTileGivenBothStartTiles(horizontalTile, startHorizontalTile, startVerticalTile); startHorizontalTile = horizontalTile; //switch (cornerDirection) { //case 0: // // Bl // startVerticalTile = corner->getVerticalTile(); // break; //case 1: // // Br // startVerticalTile = cornerVerticalTilePlane->findTile(macroXStart, macroYStart, corner->getVerticalTile()); // break; //case 2: // // Tl // startVerticalTile = corner->getVerticalTile(); // break; //case 3: // // Tr // startVerticalTile = cornerVerticalTilePlane->findTile(macroXStart, macroYStart, corner->getVerticalTile()); // break; //} cornerVerticalTilePlane->placeSolidTileGivenBothStartTiles(verticalTile, startVerticalTile, startHorizontalTile); // Remove macro from sets. //widthSortedMacros->erase(macro); //heightSortedMacros->erase(macro); // Calculate Corners' width and height. cornerHorizontalTilePlane->calculateCurrentCornersWidthAndHeight(); cornerVerticalTilePlane->calculateCurrentCornersWidthAndHeight(); // Update quadtrees. updateQuadtrees(); } delete temporarilyRemovedCorners; return !placedUnsuccessfully; }