예제 #1
0
        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);
        }
예제 #2
0
        public static PackModelsRequest CreatePackModelsRequest(int?requestedCloneCount)
        {
            PackModelsRequest packModelsRequest = new PackModelsRequest();

            foreach (var object3D in ObjectView.Objects3D)
            {
                if (object3D is STLModel3D && !(object3D is GroundPane))
                {
                    var stlModel       = object3D as STLModel3D;
                    var modelFootprint = ModelFootprint.FromModel(stlModel);
                    packModelsRequest.ModelFootprints.Add(modelFootprint);
                }
            }

            var selectedPrinter             = PrintJobManager.SelectedPrinter;
            var printerGroundPaneDimensionX = (selectedPrinter.ProjectorResolutionX / 10) * selectedPrinter.TrapeziumCorrectionFactorX;
            var printerGroundPaneDimensionY = (selectedPrinter.ProjectorResolutionY / 10) * selectedPrinter.TrapeziumCorrectionFactorY;

            packModelsRequest.BuildPlatform = new Core.Engines.PackingEngine.Rectangle()
            {
                SizeX = printerGroundPaneDimensionX,
                SizeY = printerGroundPaneDimensionY
            };

            packModelsRequest.Clearance           = UserProfileManager.UserProfile.Settings_Models_ClearanceBetweenClones;
            packModelsRequest.RequestedCloneCount = requestedCloneCount;

            return(packModelsRequest);
        }
예제 #3
0
        /// <summary>
        /// Run all packingstrategies to get their solutions
        /// </summary>
        /// <param name="packModelsRequest"></param>
        /// <param name="allPackingSolutions"></param>
        /// <param name="stopwatch"></param>
        private void getSolutions(PackModelsRequest packModelsRequest, PackingSolutions allPackingSolutions, Stopwatch stopwatch)
        {
            foreach (IPackingStrategy packingStrategy in PackingStrategies)
            {
                getSolutions(packModelsRequest, allPackingSolutions, packingStrategy);
            }

            LoggingManager.WriteToLog("PackingEngine", "Get solutions for strategies", stopwatch.ElapsedMilliseconds + "ms");
        }
예제 #4
0
        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);
        }
예제 #5
0
        public static PackingSolutions CalculatePackingSolutions(PackModelsRequest packModelsRequest)
        {
            PackingEngine packingEngine = new PackingEngine();

            packingEngine.PackingStrategies.Add(new ShelfPackLargestFirstPackingStrategy());

            var solutions = packingEngine.AnalyzeSolutions(packModelsRequest);

            return(solutions);
        }
예제 #6
0
 private static void getSolutions(PackModelsRequest packModelsRequest, PackingSolutions allPackingSolutions, IPackingStrategy packingStrategy)
 {
     try
     {
         PackingSolutions packingSolutions = packingStrategy.CreateSolutions(packModelsRequest);
         allPackingSolutions.Solutions.AddRange(packingSolutions.Solutions);
     }
     catch (Exception ex)
     {
         LoggingManager.WriteToLog("PackingEngine", "Get solutions for strategy - " + packingStrategy.GetType().Name, ex);
     }
 }
예제 #7
0
        private void determineBestSolution(PackModelsRequest packModelsRequest, PackingSolutions allPackingSolutions, Stopwatch stopwatch)
        {
            // TODO: implement determine best solution based on number of clones and biggest unused area left

            var packingSolutionsWithRequestedAmountOfClones = new List <PackingSolution>();

            if (packModelsRequest.PackingType == TypeOfPacking.DefinedNumbersOfClones)
            {
                foreach (var packageSolution in allPackingSolutions.Solutions)
                {
                    var allModelRequestsAreValid = true;
                    foreach (var modelRequest in packModelsRequest.ModelFootprints)
                    {
                        if (modelRequest.RequestedCloneCount < 5000)
                        {
                            var amountOfPackedModels = packageSolution.PackedItems.Count(s => s.ModelFootprint.Model == modelRequest.Model);
                            if (modelRequest.RequestedCloneCount >= amountOfPackedModels && amountOfPackedModels >= modelRequest.RequestedCloneCount - 1)
                            {
                            }
                            else
                            {
                                allModelRequestsAreValid = false;
                                break;
                            }
                        }
                    }

                    if (allModelRequestsAreValid)
                    {
                        packingSolutionsWithRequestedAmountOfClones.Add(packageSolution);
                    }
                }

                if (packingSolutionsWithRequestedAmountOfClones.Count > 0)
                {
                    //best solution is where there are as much as possible models
                    allPackingSolutions.BestSolution = packingSolutionsWithRequestedAmountOfClones.OrderByDescending(s => s.CloneCount).FirstOrDefault();
                }
                else
                {
                    allPackingSolutions.BestSolution = null;
                }
            }
            else
            {
                allPackingSolutions.BestSolution = allPackingSolutions.Solutions.OrderByDescending(s => s.CloneCount).FirstOrDefault();
            }


            LoggingManager.WriteToLog("PackingEngine", "Determine best solution", stopwatch.ElapsedMilliseconds + "ms");
        }
예제 #8
0
        private static ModelFootprint GetBestFitModelFootprint(PackModelsRequest packModelsRequest, int maxCloneCount, List <ModelFootprint> orderedModelFootprints, int[] modelsCloneCount, Container containerArea)
        {
            // Check best orientation for model footprints for this container
            orderedModelFootprints.DetermineOptimalModelsOrientation(containerArea, packModelsRequest.Clearance);
            // Get the first biggest model footprint which still needs to be packed
            var modelFootprintToPack = orderedModelFootprints.FirstOrDefault(footprint => modelsCloneCount[orderedModelFootprints.IndexOf(footprint)] < maxCloneCount && modelsCloneCount[orderedModelFootprints.IndexOf(footprint)] < footprint.RequestedCloneCount && containerArea.Fits(footprint));

            // If all models are packed with the max clone count to get an equal amount of models, get the next model that fits to fill up the space
            if (modelFootprintToPack == null)
            {
                modelFootprintToPack = orderedModelFootprints.FirstOrDefault(footprint => modelsCloneCount[orderedModelFootprints.IndexOf(footprint)] < footprint.RequestedCloneCount && containerArea.Fits(footprint));
            }

            return(modelFootprintToPack);
        }
예제 #9
0
        public PackingSolutions AnalyzeSolutions(PackModelsRequest packModelsRequest)
        {
            PackingSolutions allPackingSolutions = new PackingSolutions();
            Stopwatch        stopwatch           = Stopwatch.StartNew();

            getSolutions(packModelsRequest, allPackingSolutions, stopwatch);

            determineBestSolution(packModelsRequest, allPackingSolutions, stopwatch);

            stopwatch.Stop();

            allPackingSolutions.TotalDurationMs = stopwatch.ElapsedMilliseconds;
            LoggingManager.WriteToLog("PackingEngine", "Completed in", stopwatch.ElapsedMilliseconds + "ms");

            return(allPackingSolutions);
        }
예제 #10
0
        private static void FillContainer(Container container, PackModelsRequest packModelsRequest, int maxCloneCount, List <ModelFootprint> orderedModelFootprints, int[] modelsCloneCount)
        {
            ModelFootprint modelFootprint = GetBestFitModelFootprint(packModelsRequest, maxCloneCount, orderedModelFootprints, modelsCloneCount, container);

            if (modelFootprint != null)
            {
                int modelIndex = orderedModelFootprints.IndexOf(modelFootprint);
                modelsCloneCount[modelIndex]++;
                modelFootprint.CloneCount++;

                PackedItem item = PackedItem.Create(modelFootprint);
                item.CloneNumber = modelsCloneCount[modelIndex];
                item.ClearanceY  = packModelsRequest.Clearance;
                item.ClearanceX  = packModelsRequest.Clearance;
                item.PositionX   = container.PositionX;
                item.PositionY   = container.PositionY;
                container.Items.Add(item);

                Container spaceNextToModel = new Container()
                {
                    SizeX     = container.SizeX - item.TotalSizeX,
                    SizeY     = item.ModelFootprint.SizeY,
                    PositionX = item.PositionX + item.TotalSizeX,
                    PositionY = item.PositionY
                };

                if (spaceNextToModel.SizeX > packModelsRequest.Clearance)
                {
                    container.AddChild(spaceNextToModel);
                    FillContainer(spaceNextToModel, packModelsRequest, maxCloneCount, orderedModelFootprints, modelsCloneCount);
                }

                Container remainingSpaceAboveModel = new Container()
                {
                    SizeX     = container.SizeX,
                    SizeY     = container.SizeY - item.TotalSizeY,
                    PositionX = container.PositionX,
                    PositionY = container.PositionY + item.TotalSizeY
                };

                if (remainingSpaceAboveModel.SizeY > packModelsRequest.Clearance)
                {
                    container.AddChild(remainingSpaceAboveModel);
                    FillContainer(remainingSpaceAboveModel, packModelsRequest, maxCloneCount, orderedModelFootprints, modelsCloneCount);
                }
            }
        }