public PackingSolutions CreateSolutions(PackModelsRequest packModelsRequest) { PackingSolutions packingSolutions = new PackingSolutions(); Stopwatch stopwatch = Stopwatch.StartNew(); int theoreticalMaxCloneCount = packModelsRequest.DetermineMaximumCloneCountBasedOnSurfaceArea(); int maxCloneCount = theoreticalMaxCloneCount; if (packModelsRequest.RequestedCloneCount.HasValue && packModelsRequest.RequestedCloneCount.Value > 0) { maxCloneCount = Math.Min(packModelsRequest.RequestedCloneCount.Value, theoreticalMaxCloneCount); } for (int cloneCount = maxCloneCount; cloneCount > 0; cloneCount--) { PackingSolution solution = CreateSolution(packModelsRequest, cloneCount); packingSolutions.Solutions.Add(solution); if (solution.CloneCount == maxCloneCount || solution.CloneCount >= cloneCount || !solution.FootprintCloneCount.Any(f => f != solution.CloneCount)) { break; } } stopwatch.Stop(); packingSolutions.TotalDurationMs = stopwatch.ElapsedMilliseconds; return(packingSolutions); }
public PackingSolution CreateSolution(PackModelsRequest packModelsRequest, int maxCloneCount) { PackingSolution packingSolution = new PackingSolution(); Stopwatch stopwatch = Stopwatch.StartNew(); // Get model footprints based on area size packingSolution.Footprints = packModelsRequest.ModelFootprints.OrderByDescending(footprint => footprint.Area).Select(f => f.Clone()).ToList(); packingSolution.Footprints.ForEach(f => f.CloneCount = 0); packingSolution.FootprintCloneCount = new int[packingSolution.Footprints.Count]; bool buildPlatformFull = false; Container buildPlatformContainer = Container.Create(packModelsRequest.BuildPlatform); Container remainingBuildPlatformArea = buildPlatformContainer; while (!buildPlatformFull) { var firstModelFootprintToPack = GetBestFitModelFootprint(packModelsRequest, maxCloneCount, packingSolution.Footprints, packingSolution.FootprintCloneCount, remainingBuildPlatformArea); if (firstModelFootprintToPack != null) { // Create shelf Container shelf = new Container() { PositionX = remainingBuildPlatformArea.PositionX, PositionY = remainingBuildPlatformArea.PositionY, SizeX = firstModelFootprintToPack.SizeX, SizeY = packModelsRequest.BuildPlatform.SizeY }; buildPlatformContainer.AddChild(shelf); FillContainer(shelf, packModelsRequest, maxCloneCount, packingSolution.Footprints, packingSolution.FootprintCloneCount); float newPositionX = shelf.PositionX + shelf.SizeX + packModelsRequest.Clearance; remainingBuildPlatformArea = new Container() { PositionX = newPositionX, SizeX = packModelsRequest.BuildPlatform.SizeX - newPositionX, PositionY = 0, SizeY = packModelsRequest.BuildPlatform.SizeY }; } ModelFootprint modelFootprint = GetBestFitModelFootprint(packModelsRequest, maxCloneCount, packingSolution.Footprints, packingSolution.FootprintCloneCount, remainingBuildPlatformArea); buildPlatformFull = modelFootprint == null; } var allContainers = buildPlatformContainer.GetAll(); var allItems = allContainers.SelectMany(c => c.Items); packingSolution.PackedItems.AddRange(allItems); packingSolution.UnusedSpaces.AddRange(allContainers.Where(s => !s.Items.Any())); packingSolution.UnusedSpaces.Add(remainingBuildPlatformArea); packingSolution.CloneCount = packingSolution.FootprintCloneCount.Min(); stopwatch.Stop(); packingSolution.DurationMs = stopwatch.ElapsedMilliseconds; return(packingSolution); }