private int CalcMaxClonesOfModel(ModelFootprint modelFootprint, bool minModelCount)
        {
            var tmpPackModelsRequest = PackingHelper.CreatePackModelsRequest(null);

            foreach (var duplicateControl in this.spcModelControls.Panel1.Controls.OfType <DuplicateModelControl>())
            {
                if (duplicateControl.ModelFootprint.Model != modelFootprint.Model)
                {
                    tmpPackModelsRequest.ModelFootprints.First(s => s.Model == duplicateControl.ModelFootprint.Model).RequestedCloneCount = duplicateControl.TotalAmount;
                }
                else if (minModelCount)
                {
                    tmpPackModelsRequest.ModelFootprints.First(s => s.Model == duplicateControl.ModelFootprint.Model).RequestedCloneCount = duplicateControl.TotalAmount;
                }
            }

            var solutions = PackingHelper.CalculatePackingSolutions(tmpPackModelsRequest);

            if (solutions.BestSolution != null)
            {
                return(solutions.BestSolution.PackedItems.Count(s => s.ModelFootprint.Model == modelFootprint.Model));
            }
            else
            {
                return(-1); //invalid or unable to calc more models
            }
        }
        private void SetMaximumClones()
        {
            if (ObjectView.Objects3D.Count > 1)
            {
                _packModelsRequest             = PackingHelper.CreatePackModelsRequest(null);
                _packModelsRequest.PackingType = TypeOfPacking.MaxAmountOfClones;
                var solutions = PackingHelper.CalculatePackingSolutions(_packModelsRequest);

                Dictionary <ModelFootprint, int> modelFootprints = new Dictionary <ModelFootprint, int>();

                foreach (var footprint in solutions.BestSolution.Footprints)
                {
                    var duplicateControl = this.spcModelControls.Panel1.Controls.OfType <DuplicateModelControl>().First(s => s.ModelFootprint.Model == footprint.Model);
                    modelFootprints.Add(footprint, duplicateControl.TotalAmount);
                    duplicateControl.TotalAmount = footprint.CloneCount;
                }


                var cloneModelsEventArtgs = new CloneModelsEventArgs()
                {
                    PackModelsRequest  = _packModelsRequest,
                    PackagingSolutions = solutions,
                    ModelFootprints    = modelFootprints
                };
                this.ValueChanged?.Invoke(null, cloneModelsEventArtgs);
            }
            else
            {
                this.Visible = false;
            }

            //
            FillBuildPlateCompleted?.Invoke(null, null);
        }
        private void UpdateDuplicates(int previousAmount, int amount, ModelFootprint modelFootprint)
        {
            //ModelFootprint modelFootprint = this.Tag as ModelFootprint;
            if (modelFootprint != null)
            {
                var tmpPackModelsRequest = PackingHelper.CreatePackModelsRequest(null);
                foreach (var duplicateControl in this.spcModelControls.Panel1.Controls.OfType <DuplicateModelControl>())
                {
                    if (duplicateControl.ModelFootprint.Model != modelFootprint.Model)
                    {
                        tmpPackModelsRequest.ModelFootprints.First(s => s.Model == duplicateControl.ModelFootprint.Model).RequestedCloneCount = duplicateControl.TotalAmount;
                    }
                    else
                    {
                        tmpPackModelsRequest.ModelFootprints.First(s => s.Model == duplicateControl.ModelFootprint.Model).RequestedCloneCount = amount;
                    }
                }

                var solutions             = PackingHelper.CalculatePackingSolutions(tmpPackModelsRequest);
                var amountOfPackagedItems = solutions.BestSolution.PackedItems.Count(s => s.ModelFootprint.Model == modelFootprint.Model);
                if (amountOfPackagedItems < amount)
                {
                    //workaround to fix bug somewhere in packaging logic
                    tmpPackModelsRequest = PackingHelper.CreatePackModelsRequest(null);
                    foreach (var duplicateControl in this.spcModelControls.Panel1.Controls.OfType <DuplicateModelControl>())
                    {
                        if (duplicateControl.ModelFootprint.Model != modelFootprint.Model)
                        {
                            tmpPackModelsRequest.ModelFootprints.First(s => s.Model == duplicateControl.ModelFootprint.Model).RequestedCloneCount = duplicateControl.TotalAmount;
                        }
                    }
                    tmpPackModelsRequest = PackingHelper.CreatePackModelsRequest(null);
                    foreach (var duplicateControl in this.spcModelControls.Panel1.Controls.OfType <DuplicateModelControl>())
                    {
                        if (duplicateControl.ModelFootprint.Model != modelFootprint.Model)
                        {
                            tmpPackModelsRequest.ModelFootprints.First(s => s.Model == duplicateControl.ModelFootprint.Model).RequestedCloneCount = duplicateControl.TotalAmount;
                        }
                    }

                    solutions = PackingHelper.CalculatePackingSolutions(tmpPackModelsRequest);
                }

                Dictionary <ModelFootprint, int> modelFootprints = new Dictionary <ModelFootprint, int>();
                modelFootprints.Add(modelFootprint, previousAmount);

                var cloneModelsEventArgs = new CloneModelsEventArgs()
                {
                    PackModelsRequest  = tmpPackModelsRequest,
                    PackagingSolutions = solutions,
                    ModelFootprints    = modelFootprints
                };

                this.ValueChanged?.Invoke(null, cloneModelsEventArgs);
            }
        }
        private void SceneControlModelDuplicate_Load(object sender, EventArgs e)
        {
            var font = FontManager.Montserrat14Regular;

            this.lblErrorMessage.Font = font;

            this.btnDuplicatesFillPlate.Font = FontManager.Montserrat14Regular;

            if (ObjectView.Objects3D.Count > 1)
            {
                this._packModelsRequest = PackingHelper.CreatePackModelsRequest(null);
            }
        }
        public void SendRadiuses(int matchId, ushort playerId, Dictionary <ushort, ushort> radiuses, bool rudp = false)
        {
            var length = PackingHelper.GetByteLength(radiuses);

            if (length > PackingHelper.MaxSingleMessageSize)
            {
                log.Warn($"MatchId {matchId}, playerId {playerId}: превышение размера сообщения в {nameof(SendRadiuses)} ({length} из {PackingHelper.MaxSingleMessageSize}), выполняется разделение сообщения.");
                var messagesCount = (length - 1) / PackingHelper.MaxSingleMessageSize + 1;
                var dictionaries  = radiuses.Split(messagesCount);
                for (var i = 0; i < dictionaries.Length; i++)
                {
                    var message = new RadiusesMessage(dictionaries[i]);
                    SendUdp(matchId, playerId, message, rudp);
                }
            }
            else
            {
                var message = new RadiusesMessage(radiuses);
                SendUdp(matchId, playerId, message, rudp);
            }
        }
        public void SendDestroys(int matchId, ushort playerId, ushort[] destroyedIds)
        {
            var length = PackingHelper.GetByteLength(destroyedIds);

            if (length > PackingHelper.MaxSingleMessageSize)
            {
                log.Warn($"MatchId {matchId}, playerId {playerId}: превышение размера сообщения в {nameof(SendDestroys)} ({length} из {PackingHelper.MaxSingleMessageSize}), выполняется разделение сообщения.");
                var messagesCount = (length - 1) / PackingHelper.MaxSingleMessageSize + 1;
                var arrays        = destroyedIds.Split(messagesCount);
                for (var i = 0; i < arrays.Length; i++)
                {
                    var message = new DestroysMessage(arrays[i]);
                    SendUdp(matchId, playerId, message, true);
                }
            }
            else
            {
                var message = new DestroysMessage(destroyedIds);
                SendUdp(matchId, playerId, message, true);
            }
        }
        internal void RefreshCurrentDuplicates()
        {
            if (ObjectView.Objects3D.Count > 1)
            {
                _packModelsRequest = PackingHelper.CreatePackModelsRequest(null);
                var solutions = PackingHelper.CalculatePackingSolutions(_packModelsRequest);
                this.spcModelControls.Panel1.Controls.Clear();
                int i             = 0;
                var summaryHeight = 0;
                this.Height = 215;
                foreach (var model in ObjectView.Objects3D)
                {
                    if (model != null && (!(model is GroundPane)))
                    {
                        var stlModel = model as STLModel3D;

                        ModelFootprint modelFootprint = null;
                        if (solutions.BestSolution == null)
                        {
                            modelFootprint       = new ModelFootprint(stlModel.RightPoint - stlModel.LeftPoint, stlModel.FrontPoint - stlModel.BackPoint);
                            modelFootprint.Model = stlModel;
                        }
                        else
                        {
                            modelFootprint = solutions.BestSolution.Footprints.First(f => f.Model == stlModel);
                        }

                        if (i > 0)
                        {
                            this.Height += defaultItemHeight;
                        }

                        DuplicateModelControl duplicateModelControl = new DuplicateModelControl(modelFootprint);
                        if (i % 2 != 0)
                        {
                            duplicateModelControl.BackgroundColor = Color.FromArgb(237, 237, 237);
                        }
                        else
                        {
                            duplicateModelControl.BackgroundColor = Color.FromArgb(224, 224, 224);
                        }

                        duplicateModelControl.Left = 0;
                        duplicateModelControl.Top  = summaryHeight;
                        duplicateModelControl.DuplicatesCount_KeyUp += DuplicateModelControl_DuplicatesCount_KeyPress;
                        duplicateModelControl.DuplicatesMinus_Click += DuplicateModelControl_DuplicatesMinus_Click;
                        duplicateModelControl.DuplicatesPlus_Click  += DuplicateModelControl_DuplicatesPlus_Click;
                        this.spcModelControls.Panel1.Controls.Add(duplicateModelControl);
                        summaryHeight += defaultItemHeight;
                        i++;
                    }
                }
            }
            else
            {
                this.Visible = false;

                //show message
                var tt = new SceneControlManualToolTip();
                tt.SetText("No models available");

                var modelActionsToolbar    = SceneControlToolbarManager.ModelActionsToolbar;
                var btnDuplicationButton   = modelActionsToolbar.ModelDuplicateButton;
                var duplicationButtonPoint = new Point(btnDuplicationButton.Left + btnDuplicationButton.Width + modelActionsToolbar.Left + 16, btnDuplicationButton.Top + modelActionsToolbar.Top);
                duplicationButtonPoint.Y += (btnDuplicationButton.Height / 2) - (tt.Height / 2);
                tt.ShowToolTip(duplicationButtonPoint);

                ToolbarActionsManager.Update(Core.Enums.MainFormToolStripActionType.btnSelectPressed, frmStudioMain.SceneControl, null);
            }
        }