Exemple #1
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);
        }
Exemple #2
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);
        }
Exemple #3
0
        public ModelFootprint Clone()
        {
            ModelFootprint clonedFootprint = new ModelFootprint(this.SizeX, this.SizeY, this.Color);

            clonedFootprint.Model               = this.Model;
            clonedFootprint.PositionX           = this.PositionX;
            clonedFootprint.PositionY           = this.PositionY;
            clonedFootprint.RequestedCloneCount = this.RequestedCloneCount;
            clonedFootprint.RotateModel         = this.RotateModel;
            clonedFootprint.CloneCount          = this.CloneCount;
            return(clonedFootprint);
        }
Exemple #4
0
        public static PackedItem Create(ModelFootprint modelFootprint)
        {
            PackedItem packedItem = new PackedItem()
            {
                ModelFootprint = modelFootprint,
                SizeX          = modelFootprint.SizeX,
                SizeY          = modelFootprint.SizeY,
                RotateModel    = modelFootprint.RotateModel,
            };

            return(packedItem);
        }
Exemple #5
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);
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// Create a model footprint for a STL model
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static ModelFootprint FromModel(STLModel3D model)
        {
            ModelFootprint modelFootprint = new ModelFootprint();

            modelFootprint.Model = model;
            if (model.SupportBasement)
            {
                if (model.SupportBasementStructure != null)
                {
                    model.SupportBasementStructure.UpdateBoundries();
                }
            }

            modelFootprint.SizeX = Math.Abs(model.FootprintRightPoint - model.FootprintLeftPoint);
            modelFootprint.SizeY = Math.Abs(model.FootprintBackPoint - model.FootprintFrontPoint);

            modelFootprint.Color = model.Color;

            return(modelFootprint);
        }
Exemple #7
0
        public static void DetermineOptimalModelOrientation(this ModelFootprint modelFootprint, Rectangle container, float clearance)
        {
            // Optimal orientation is the orientation that allows the most amount of clones of the model in total on the buildplate, with clearance
            // TODO: there may be a better way to calculate with clearance since the clearance is not needed on the edges of the buildplatform

            // Normal orientation
            int normalOrientationRows       = DetermineMaxRepetitions(container.SizeY, modelFootprint.SizeY + 0.0f * clearance);
            int normalOrientationColumns    = DetermineMaxRepetitions(container.SizeX, modelFootprint.SizeX + 0.0f * clearance);
            int normalOrientationCloneCount = normalOrientationRows * normalOrientationColumns;

            // Rotated 90 degrees
            int  rotatedOrientationRows       = DetermineMaxRepetitions(container.SizeY, modelFootprint.SizeX + 0.0f * clearance);
            int  rotatedOrientationColumns    = DetermineMaxRepetitions(container.SizeX, modelFootprint.SizeY + 0.0f * clearance);
            int  rotatedOrientationCloneCount = rotatedOrientationRows * rotatedOrientationColumns;
            bool rotateModel = rotatedOrientationCloneCount > normalOrientationCloneCount;

            //The model may already be rotated and SizeX and SizeY may already return the rotated value, so only apply rotation by inverting current value if needed
            if (rotateModel)
            {
                modelFootprint.RotateModel = !modelFootprint.RotateModel;
            }
        }