def createAndAddNewGrid(self, width, article_name='default', material='kokos', brand='kokos', color='naturel'): if self.rectangle.getBrand().lower( ) == 'kokos' and self.rectangle.getGridWidth() == 100: grid_height = 1230 elif self.rectangle.getBrand().lower( ) == 'kokos' and self.rectangle.getGridWidth() == 200: grid_height = 605 else: grid_height = 980 try: grid = Grid(width=width, height=grid_height, article_name=article_name, material=material, name=self.grids[-1].getName() + 1, brand=brand, color=color, stacked_rectangles=[]) self.grids.append(grid) self.db_manager.addGrid(grid) print("Created and added new grid to database") except IndexError: grid = Grid(width=200, height=grid_height, name=1) self.grids.append(grid) self.db_manager.addGrid(grid) print("Created and added initial grid to database")
def getGrid(self, grid_number, for_cutting=False): """ Parameters ---------- for_cutting: get the rectangles with the exact sizes (in mm) """ query = {"name": grid_number} cursor = self.grids_collection.find(query) for document in cursor: grid = Grid(width=document['width'], height=document['height'], article_name=document['article_name'], brand=document['brand'], material=document['material'], color=document['color'], name=document['name'], is_cut=document['isCut']) if for_cutting == True: rectangles = self.getRectangles(grid, for_cutting) else: rectangles = self.getRectangles(grid) grid.setStackedRectangles(rectangles) return grid
def getGridsCutByWidthBrandColor(self, width=100, brand='kokos', color='naturel'): grids = [] query = {} if brand != 'all': query["brand"] = brand if color != 'all': query["color"] = color if grid_width != 'all': query["grid_width"] = grid_width cursor = self.grids_collection.find(query) for document in cursor: grid = Grid(width=document['width'], height=document['height'], article_name=document['article_name'], material=document['material'], brand=document['brand'], color=document['color'], name=document['name'], is_cut=document['isCut']) rectangles = self.getRectangles(grid) grid.setStackedRectangles(rectangles) if grid.isCut(): print("Loaded grid " + str(document["name"]) + " from database") grids.append(grid) return grids
def setUp(self): self.rectangle_4 = Rectangle(50, 80, 4) self.rectangle_5 = Rectangle(50, 80, 5) self.grid_1 = Grid(200, 1500, 1) self.grid_2 = Grid(100, 100, 2) self.grid_3 = Grid(100, 80, 3)
def testIsValidPosition(self): self.grid_2 = Grid(100, 100, 2) self.rectangle_4.setPosition([25, 40]) self.rectangle_5.setPosition([24, 40]) self.grid_2.addRectangle(self.rectangle_4) self.assertFalse(self.grid_2.isValidPosition(self.rectangle_5)) self.rectangle_5.setPosition([76, 40]) self.assertFalse(self.grid_2.isValidPosition(self.rectangle_5))
def getGridsNotFull(self, width=100, brand='kokos', color='naturel'): try: grids = [] query = {"width": width, "brand": brand, "color": color} cursor = self.grids_collection.find(query) for document in cursor: print("Loaded grid " + str(document["name"]) + " from database") grid = Grid(width=document['width'], height=document['height'], article_name=document['article_name'], material=document['material'], brand=document['brand'], color=document['color'], name=document['name'], is_cut=document['isCut']) rectangles = self.getRectangles(grid) grid.setStackedRectangles(rectangles) grid.checkAndSetFull() if not grid.isFull(): grids.append(grid) except: pass return grids
def getGridsNotCut(self, sort=False): grids = [] cursor = self.grids_collection.find({}) for document in cursor: print("getGridsNotCut material = " + str(document['material'])) grid = Grid(width=document['width'], height=document['height'], name=document['name'], article_name=document['article_name'], material=document['material'], color=document['color'], brand=document['brand'], is_cut=document['isCut']) rectangles = self.getRectangles(grid) grid.setStackedRectangles(rectangles) if not grid.isCut(): print("Loaded grid " + str(document["name"]) + " from database") grids.append(grid) if sort == True: grids = sorted(grids, key=lambda g: g.getWidth(), reverse=True) print("Grid widths are " + str([grid.getWidth() for grid in grids])) print("Grid heights are " + str([grid.getHeight() for grid in grids])) return grids
def __init__(self, data_logger=DataLogger()): self.db_manager = DatabaseManager() self.setStandardSizesToFill([]) self.setFillOrdersWithSmallerGridWidths(False) self.rectangles = [] self.is_stacking = False # current rectangle to stack in current grid self.rectangle = Rectangle() self.grid = Grid() self.setDataLogger(data_logger) # stacking position of current rectangle self.stacking_position = [] # stacking position of current rectangle rotated self.stacking_position_rotated = []
def getAllGrids(self): grids = [] cursor = self.grids_collection.find({}) for document in cursor: print("Loaded grid " + str(document["name"]) + " from database") grid = Grid(width=document['width'], height=document['height'], article_name=document['article_name'], brand=document['brand'], material=document['material'], color=document['color'], name=document['name'], is_cut=document['isCut']) rectangles = self.getRectangles(grid) grid.setStackedRectangles(rectangles) grids.append(grid) return grids
class GridTest(unittest.TestCase): def setUp(self): self.rectangle_4 = Rectangle(50, 80, 4) self.rectangle_5 = Rectangle(50, 80, 5) self.grid_1 = Grid(200, 1500, 1) self.grid_2 = Grid(100, 100, 2) self.grid_3 = Grid(100, 80, 3) def tearDown(self): pass def testIsOutOfGrid(self): self.rectangle_4.setPosition([25, 40]) self.assertFalse(self.grid_2.isOutOfGrid(self.rectangle_4)) self.grid_2.addRectangle(self.rectangle_4) self.rectangle_5.setPosition([75, 40]) self.assertFalse(self.grid_2.isOutOfGrid(self.rectangle_5)) self.rectangle_5.setPosition([76, 40]) self.assertTrue(self.grid_2.isOutOfGrid(self.rectangle_5)) self.rectangle_5.setPosition([75, 40]) self.assertFalse(self.grid_3.isOutOfGrid(self.rectangle_5)) self.rectangle_5.setPosition([75, 41]) self.assertTrue(self.grid_3.isOutOfGrid(self.rectangle_5)) def testIsValidPosition(self): self.grid_2 = Grid(100, 100, 2) self.rectangle_4.setPosition([25, 40]) self.rectangle_5.setPosition([24, 40]) self.grid_2.addRectangle(self.rectangle_4) self.assertFalse(self.grid_2.isValidPosition(self.rectangle_5)) self.rectangle_5.setPosition([76, 40]) self.assertFalse(self.grid_2.isValidPosition(self.rectangle_5))
class Stacker(object): """ Contains the algorithm for stacking rectangles in a grid in 2D. The rectangles are first sorted at centimeter accuracy. First the rectangles are sorted using in descending order based on the area, after which they are stacked to the most lower left position. After that the rectangles are shrunken to their exact millimeter size and moved left and downwards until they cannot be moved further. The result is a millimeter accuracy stacked grid. """ def __init__(self, data_logger=DataLogger()): self.db_manager = DatabaseManager() self.setStandardSizesToFill([]) self.setFillOrdersWithSmallerGridWidths(False) self.rectangles = [] self.is_stacking = False # current rectangle to stack in current grid self.rectangle = Rectangle() self.grid = Grid() self.setDataLogger(data_logger) # stacking position of current rectangle self.stacking_position = [] # stacking position of current rectangle rotated self.stacking_position_rotated = [] def setDataLogger(self, data_logger): self.data_logger = data_logger def getDataLogger(self): return self.data_logger def setRectangle(self, rectangle): self.rectangle = rectangle def setExcelParser(self, path, file_name): self.excel_parser = ExcelParser(data_logger=self.data_logger, path=path, file_name=file_name) def stackingStopped(self): return not self.is_stacking def startStacking(self): self.is_stacking = True def stopStacking(self): self.is_stacking = False def setGrid(self, grid): print("Set grid to " + str(grid.getName())) self.grid = grid def getGrid(self): return self.grid def setStandardSizesToFill(self, sizes): self.standard_sizes_to_fill = sizes def getStandardSizesToFill(self): return self.standard_sizes_to_fill def setFillOrdersWithSmallerGridWidths(self, should_be_filled): self.fill_orders_with_smaller_grid_widths = should_be_filled def getFillSmallerGridWidths(self): return self.fill_smaller_grid_widths def getUnstackedRectangles(self): return [ rectangle for rectangle in self.rectangles if not rectangle.isStacked() ] def setCoupage(self, coupage): self.coupage = coupage def getCoupage(self): return self.coupage def start(self, automatic=True): """ Starts stacking the current unstacked rectangles from database in self.grid Parameters ----------- automatic: Automatically create grids when not available and stack all unstacked rectangles in these grids (loop over all the grids instead of only self.grid) When automatic is false, the user should manually set a grid to be used for stacking. """ self.start_time = time.time() self.getAndExportCoupages() self.is_stacking = True # self.loadOrdersAndAddToDatabase() self.getAllUnstackedRectanglesFromDatabaseAndSortOnArea() total_amount_of_unstacked_rectangles = len( self.getUnstackedRectangles()) while self.anyUnstackedRectangles() and not self.stackingStopped(): if automatic: self.createGridInDatabaseIfNotAvailable() self.grids = self.db_manager.getGridsNotCut(sort=True) else: self.grids = [] self.grids.append(self.grid) for grid in self.grids: self.rectangles = [] self.setGrid(grid) self.getUnstackedRectanglesFromDatabaseMatchingAllGridPropertiesSortedOnArea( ) self.stackUnstackedRectanglesInGrid() # some grids are empty and should not be exported if not grid.isEmpty() and len( self.getUnstackedRectangles()) == 0: if self.fill_orders_with_smaller_grid_widths: self.shrinkGridToHeighestVerticalStackedPoint() self.stackOrdersWithSmallerGridWidths() if len(self.standard_sizes_to_fill ) > 0 and self.grid.getBrand().lower() == "kokos": self.shrinkGridToHeighestVerticalStackedPoint() self.stackStandardRectangles() self.enlargeGridToStandardSize() # break out of loop when operator presses stop button if self.stackingStopped(): break self.getAllUnstackedRectanglesFromDatabaseAndSortOnArea() self.optimizeOnMillimetersAndExportNonEmptyGrids() self.total_time = time.time() - self.start_time self.data_logger.setTotalExecutionTime(self.total_time) self.data_logger.setSuccessfullyStackedRectangles( total_amount_of_unstacked_rectangles) self.data_logger.storeData() def optimizeOnMillimetersAndExportNonEmptyGrids(self): self.grids = self.db_manager.getGridsNotCut(sort=True) for grid in self.grids: if not grid.isEmpty(): self.setGrid(grid) self.convertRectanglesToMillimetersOptimizeAndExportGrid() def stackOrdersWithSmallerGridWidths(self): self.getUnstackedRectanglesOfAllSmallerGridWidthsThanOriginalSortedOnArea( ) self.stackUnstackedRectanglesInGrid() def shrinkGridToHeighestVerticalStackedPoint(self): # set height to heighest point because we only want to stack in the gaps # of the stack, not add more at the top self.grid.setHeight(self.grid.getHighestVerticalPoint()) self.db_manager.updateGrid(self.grid) def enlargeGridToStandardSize(self): if self.grid.getBrand().lower() == 'kokos' and self.grid.getWidth( ) == 100: grid_height = 1230 elif self.grid.getBrand().lower() == 'kokos' and self.grid.getWidth( ) == 200: grid_height = 605 else: grid_height = 980 self.grid.setHeight(grid_height) self.db_manager.updateGrid(self.grid) def getUncutAreasOfGrids(self): grids = self.db_manager.getGridsNotCut() result = [] for grid in grids: if not grid.isEmpty(): result.append(grid.getUncutArea()) return result def getAndExportCoupages(self): coupages = self.db_manager.getUnstackedRectangles( for_cutting=True, coupage_batch="coupage") for coupage in coupages: self.setCoupage(coupage) self.rotateCoupageToLargestSideUpwards() self.exportAndUpdateCoupage() def rotateCoupageToLargestSideUpwards(self): _width = self.coupage.getWidth() _height = self.coupage.getHeight() if _width > _height: print("Coupage width is larger than height") width, height = Helper.swap(_width, _height) print("Width before swap = " + str(self.coupage.getWidth())) self.coupage.setWidth(width) self.coupage.setHeight(height) print("Width after swap = " + str(self.coupage.getWidth())) self.db_manager.updateRectangle(self.coupage) def exportAndUpdateCoupage(self): self.coupage.toDxf(for_prime_center=True) self.coupage.toZcc() self.coupage.setStacked() self.db_manager.updateRectangle(self.coupage) def loadOrdersAndAddToDatabase(self): try: self.rectangles = self.excel_parser.getUnstackedRectangles() self.db_manager.addRectangles(self.rectangles) except EmptyExcelError: print("Excel file is empty!") def computeRectangleOrderArea(self, rectangles): areas = [x.getArea() for x in rectangles] indices_descending_order = sorted(range(len(areas)), key=lambda k: areas[k]) rectangles_descending_area_order = [] for idx in indices_descending_order: rectangles_descending_area_order.append(rectangles[idx]) return list(reversed(rectangles_descending_area_order)) def stackStandardRectangles( self, sizes=Rectangle.getStandardSizesSortedOnMostSold()): print("Try stacking standard rectangles") for size in self.standard_sizes_to_fill: while True: if not self.stackingStopped(): rectangle = Rectangle( width=size[0], height=size[1], client_name="Voorraad_" + str(size[0]) + "x" + str(size[1]) + "_" + str(uuid.uuid4())[-4:], name="Voorraad_" + str(size[0]) + "x" + str(size[1]) + "_" + str(uuid.uuid4())[-4:], grid_width=self.grid.getWidth(), brand=self.grid.getBrand(), color=self.grid.getColor()) self.db_manager.addRectangle(rectangle) self.setRectangle(rectangle) try: print("Grid height = " + str(self.grid.getHeight())) self.stackOriginalOrRotatedRectangleAndUpdateDatabase() except RotatedAndOriginalRectangleDoNotFitError: self.db_manager.removeRectangle(rectangle) break else: break def getUnstackedRectanglesOfAllSmallerGridWidthsThanOriginalSortedOnArea( self): self.rectangles = [] unstacked_rectangles = self.db_manager.getUnstackedRectangles( color=self.grid.getColor(), brand=self.grid.getBrand(), for_cutting=True) for rectangle in unstacked_rectangles: if rectangle.getGridWidth() <= self.grid.getWidth(): self.rectangles.append(rectangle) self.rectangles = self.computeRectangleOrderArea(self.rectangles) for rectangle in self.rectangles: rectangle.roundWidth() rectangle.roundHeight() def anyUnstackedRectangles(self): return len(self.getUnstackedRectangles()) > 0 def createGridInDatabaseIfNotAvailable(self): for rectangle in self.rectangles: if not self.isGridAvailable(rectangle): print("Grid not available") print("Create unique grid with material " + str(rectangle.getMaterial())) print("Create unique grid with article name " + str(rectangle.getArticleName())) if rectangle.getBrand().lower( ) == 'kokos' and rectangle.getGridWidth() == 100: grid_height = 1230 elif rectangle.getBrand().lower( ) == 'kokos' and rectangle.getGridWidth() == 200: grid_height = 605 else: grid_height = 980 self.db_manager.createUniqueGrid( width=rectangle.getGridWidth(), height=grid_height, article_name=rectangle.getArticleName(), material=rectangle.getMaterial(), color=rectangle.getColor(), brand=rectangle.getBrand()) def getUnstackedRectanglesFromDatabaseMatchingAllGridPropertiesSortedOnArea( self): self.rectangles = self.db_manager.getUnstackedRectangles( color=self.grid.getColor(), brand=self.grid.getBrand(), grid_width=self.grid.getWidth(), for_cutting=True) self.rectangles = self.computeRectangleOrderArea(self.rectangles) for rectangle in self.rectangles: rectangle.roundWidth() rectangle.roundHeight() def getUnstackedRectanglesFromDatabaseMatchingGridColorBrandSortedOnArea( self): self.rectangles = self.db_manager.getUnstackedRectangles( color=self.grid.getColor(), brand=self.grid.getBrand(), for_cutting=True) self.rectangles = self.computeRectangleOrderArea(self.rectangles) for rectangle in self.rectangles: rectangle.roundWidth() rectangle.roundHeight() def getAllUnstackedRectanglesFromDatabaseAndSortOnArea(self): self.rectangles = self.db_manager.getUnstackedRectangles( for_cutting=True) self.rectangles = self.computeRectangleOrderArea(self.rectangles) for rectangle in self.rectangles: rectangle.roundWidth() rectangle.roundHeight() def isGridAvailable(self, rectangle): grid_width = rectangle.getGridWidth() color = rectangle.getColor() brand = rectangle.getBrand() print("Is grid available?") print("Color: " + rectangle.getColor()) print("Brand: " + rectangle.getBrand()) return len( self.db_manager.getGridsNotCutByWidthBrandColor( width=grid_width, color=color, brand=brand)) > 0 def rectangleAndGridPropertiesMatch(self): return (self.grid.getBrand() == self.rectangle.getBrand()) and ( self.grid.getColor() == self.rectangle.getColor()) def createNewGridAndStackRectangle(self): if self.rectangle.getBrand().lower( ) == 'kokos' and self.rectangle.getGridWidth() == 100: grid_height = 1230 elif self.rectangle.getBrand().lower( ) == 'kokos' and self.rectangle.getGridWidth() == 200: grid_height = 605 else: grid_height = 980 new_grid = self.db_manager.createUniqueGrid( width=self.rectangle.getGridWidth(), height=grid_height, article_name=self.rectangle.getArticleName(), material=self.rectangle.getMaterial(), brand=self.rectangle.getBrand(), color=self.rectangle.getColor()) self.setGrid(new_grid) # for some reason new_grid starts out filled in an iteration self.db_manager.emptyGrid(new_grid) try: self.stackOriginalOrRotatedRectangleAndUpdateDatabase() except RotatedAndOriginalRectangleDoNotFitError: print( "Something went wrong, rectangle does not fit in completely new grid" ) def convertRectanglesToMillimetersOptimizeAndExportGrid(self): print("Optimizing grid " + str(self.grid.getName()) + " and exporting to DXF...") self.getRectanglesExactWidthHeight() self.grid.empty() # size to move rectangles in x and y direction step_size = 0.001 for exact_rectangle in self.exact_rectangles: print("Optimizing " + str(exact_rectangle.getName()) + '.....') self.is_optimized_x = False self.is_optimized_y = False # copy needed because otherwise variables have the same address self.optimized_rectangle = copy.deepcopy(exact_rectangle) while not self.is_optimized_x: self.moveRectangleHorizontally(step_size) while not self.is_optimized_y: self.moveRectangleVertically(step_size) self.db_manager.updateRectangle(self.optimized_rectangle) self.grid.addRectangle(self.optimized_rectangle) self.grid.toDxf(for_prime_center=True, remove_overlap=True) self.grid.toZcc() def getRectanglesExactWidthHeight(self): self.exact_rectangles = self.db_manager.getRectangles(self.grid, for_cutting=True, sort=True) # self.grid.setStackedRectangles(self.exact_rectangles) def moveRectangleHorizontally(self, step_size): self.grid.removeRectangle(self.optimized_rectangle) x = self.optimized_rectangle.getPosition()[0] y = self.optimized_rectangle.getPosition()[1] x_new = x - step_size self.optimized_rectangle.setPosition([x_new, y]) if not self.grid.isValidPosition(self.optimized_rectangle): print("Cannot optimize further in x direction") self.optimized_rectangle.setPosition([x, y]) print(self.optimized_rectangle) self.is_optimized_x = True else: pass # move x to x_new def moveRectangleVertically(self, step_size): self.grid.removeRectangle(self.optimized_rectangle) x = self.optimized_rectangle.getPosition()[0] y = self.optimized_rectangle.getPosition()[1] y_new = y - step_size self.optimized_rectangle.setPosition([x, y_new]) if not self.grid.isValidPosition(self.optimized_rectangle): print("Cannot optimize further in y direction") self.optimized_rectangle.setPosition([x, y]) self.is_optimized_y = True else: pass # move y to y_new def createAndAddNewGrid(self, width, article_name='default', material='kokos', brand='kokos', color='naturel'): if self.rectangle.getBrand().lower( ) == 'kokos' and self.rectangle.getGridWidth() == 100: grid_height = 1230 elif self.rectangle.getBrand().lower( ) == 'kokos' and self.rectangle.getGridWidth() == 200: grid_height = 605 else: grid_height = 980 try: grid = Grid(width=width, height=grid_height, article_name=article_name, material=material, name=self.grids[-1].getName() + 1, brand=brand, color=color, stacked_rectangles=[]) self.grids.append(grid) self.db_manager.addGrid(grid) print("Created and added new grid to database") except IndexError: grid = Grid(width=200, height=grid_height, name=1) self.grids.append(grid) self.db_manager.addGrid(grid) print("Created and added initial grid to database") def stackUnstackedRectanglesInGrid(self, smaller=False): for rectangle in self.rectangles: self.setRectangle(rectangle) if self.rectangleAndGridPropertiesMatch( ) and not rectangle.isStacked(): try: self.stackOriginalOrRotatedRectangleAndUpdateDatabase() except RotatedAndOriginalRectangleDoNotFitError: print("Both rotated and original do not fit in grid") self.createNewGridAndStackRectangle() continue # stop the loop if user presses stop button if self.stackingStopped(): break def stackOriginalOrRotatedRectangleAndUpdateDatabase(self): self.chooseOriginalOrRotatedRectangle() self.updateUnstackedRectangleInDatabase() def chooseOriginalOrRotatedRectangle(self): try: self.computeRotatedRectangleStackingPosition() except RectangleDoesNotFitError: print("Rotated rectangle does not fit") pass try: self.computeOriginalRectangleStackingPosition() except RectangleDoesNotFitError: print("Original rectangle does not fit") pass if self.isRotatedRectangleMoreOptimal(): self.updateStackingPositionToRotatedInDatabase() if self.stacking_position_rotated[0] == self.grid.getWidth( ) and self.stacking_position_rotated[1] == self.grid.getHeight(): if self.stacking_position[0] == self.grid.getWidth( ) and self.stacking_position[1] == self.grid.getHeight(): raise RotatedAndOriginalRectangleDoNotFitError def computeRotatedRectangleStackingPosition(self): print("Computing stacking position for rotated rectangle " + str(self.rectangle.getName())) self.rectangle.rotate() self.stacking_position_rotated = self.computeStackingPosition() self.rectangle.rotate() if self.stacking_position_rotated[0] == self.grid.getWidth( ) and self.stacking_position_rotated[1] == self.grid.getHeight(): raise RectangleDoesNotFitError def computeOriginalRectangleStackingPosition(self): print("Computing stacking position for original rectangle " + str(self.rectangle.getName())) self.stacking_position = self.computeStackingPosition() if self.stacking_position[0] == self.grid.getWidth( ) and self.stacking_position[1] == self.grid.getHeight(): raise RectangleDoesNotFitError def isRotatedRectangleMoreOptimal(self): return np.linalg.norm(self.stacking_position_rotated) < np.linalg.norm( self.stacking_position) def updateStackingPositionToRotatedInDatabase(self): self.rectangle.rotate() self.stacking_position = copy.deepcopy(self.stacking_position_rotated) # get exact width height to update database correctly # rotate this rectangle rectangle_exact = self.db_manager.getRectangle( self.rectangle.getName(), for_cutting=True) rectangle_exact.rotate() self.db_manager.updateRectangle(rectangle_exact) def updateUnstackedRectangleInDatabase(self): self.rectangle.setPosition(self.stacking_position) self.rectangle.setStacked() self.rectangle.setGridNumber(self.grid.getName()) # get exact rectangle width and height rectangle_exact = self.db_manager.getRectangle( self.rectangle.getName(), for_cutting=True) width_exact = rectangle_exact.getWidth() height_exact = rectangle_exact.getHeight() # check if rectangle was rotated in start function w = int(np.ceil(width_exact)) # if w % 2 > 0: # w += 1 if w == self.rectangle.getHeight(): t = height_exact height_exact = width_exact width_exact = t # set rectangle width height back to the exact ones self.rectangle.setWidth(width_exact) self.rectangle.setHeight(height_exact) for rectangle in self.rectangles: if rectangle.getName() == self.rectangle.getName(): rectangle.setStacked() self.grid.addRectangle(self.rectangle) self.db_manager.updateRectangle(self.rectangle) self.db_manager.updateGrid(self.grid) def computeStackingPosition(self): stacking_position = [self.grid.getWidth(), self.grid.getHeight()] if self.grid.getWidth() > self.rectangle.getWidth(): for x in self.getHorizontalLoopRange(): for y in self.getVerticalLoopRange(): position = np.array([x, y]) self.rectangle.setPosition(position) if self.grid.isValidPosition( self.rectangle) and np.linalg.norm( position) < np.linalg.norm(stacking_position): stacking_position = position elif self.grid.getWidth() == self.rectangle.getWidth(): x = self.rectangle.getWidth() / 2 for y in self.getVerticalLoopRange(): position = np.array([x, y]) self.rectangle.setPosition(position) if self.grid.isValidPosition( self.rectangle) and np.linalg.norm( position) < np.linalg.norm(stacking_position): stacking_position = position return stacking_position def getHorizontalLoopRange(self): if self.rectangle.getWidth() % 2 > 0: width = self.rectangle.getWidth() + 1 else: width = self.rectangle.getWidth() return reversed( range(int(width / 2), int(self.grid.getWidth() - width / 2) + 1)) def getVerticalLoopRange(self): if self.rectangle.getHeight() % 2 > 0: height = self.rectangle.getHeight() + 1 else: height = self.rectangle.getHeight() return reversed( range(int(height / 2), int(self.grid.getHeight() - height / 2) + 1))
def createUniqueGrid(self, width, height=None, article_name='', material='kokos', brand='kokos', color='naturel'): brand_lower_case = brand.lower() material_lower_case = material.lower() # only do this when the height is not specified if height == None: if brand_lower_case == 'kokos' and width == 100: height = 1225 elif brand_lower_case == 'kokos' and width == 200: height = 600 # ambiant except lobby elif brand_lower_case == 'ambiant' and material_lower_case.split( )[1] != 'lobby' and width == 123: height = 975 elif brand_lower_case == 'ambiant' and material_lower_case.split( )[1] != 'lobby' and width == 193: height = 600 # ambiant lobby elif brand_lower_case == 'ambiant' and material_lower_case.split( )[1] == 'lobby' and width == 123: height = 975 elif brand_lower_case == 'ambiant' and material_lower_case.split( )[1] == 'lobby' and width == 200: height = 600 # forbo elif brand_lower_case.split()[0] == 'forbo' and width == 98: height = 975 elif brand_lower_case.split()[0] == 'forbo' and width == 148: height = 975 elif brand_lower_case.split()[0] == 'forbo' and width == 198: height = 600 # zeno protect elif brand_lower_case.split()[0] == 'zeno' and width == 98: height = 975 elif brand_lower_case.split()[0] == 'zeno' and width == 198: height = 600 # ondervloer elif brand_lower_case == 'ondervloer 5 mm' and width == 135: height = 700 elif brand_lower_case == 'ondervloer 3,6 mm' and width == 130: height = 1100 elif brand_lower_case.split()[0] == 'squid' and width == 137: height = 1500 # TODO: might want to throw an exception here else: height = 980 try: used_names = self.listUsedGridNames() sorted_names = sorted(used_names) unique_name = int(sorted_names[-1] + 1) print("Creating unique grid with number: " + str(unique_name)) grid = Grid(width=width, height=height, name=unique_name, article_name=article_name, material=material, brand=brand, color=color) self.addGrid(grid) except IndexError: print("No grids available yet") print("Creating first grid") grid = Grid(width=width, height=height, name=1, article_name=article_name, material=material, brand=brand, color=color) print(grid.color) print(grid.brand) self.addGrid(grid) return grid
from rectangle_packing.grid import Grid from rectangle_packing.stacker import Stacker from rectangle_packing.rectangle import Rectangle from rectangle_packing.excel_parser import ExcelParser from rectangle_packing.database_manager import DatabaseManager import cProfile if __name__ == "__main__": stacker = Stacker() excel_parser = ExcelParser("./example/paklijsten/", "paklijst.xlsx") grid = Grid(name="0", width=130, height=1500, brand="Ambiant", color="2400.0205") grid.setDxfDrawing("./example/grids/", "example.dxf") db_manager = DatabaseManager() prof = cProfile.Profile() db_manager.clearDatabase() rectangles = excel_parser.getUnstackedRectangles() db_manager.addRectangles(rectangles) stacker.setGrid(grid) prof.enable() stacker.start(automatic=False) prof.disable() prof.print_stats()