/// <summary> Смасштабировать и повернуть изображение профиля по опорным точкам </summary>
        private void UpdateProfileImageByControlPoints()
        {
            #region Обрезание

            var image = ProgramCore.Project.ProfileImage;
            var leftX = (int)(profileControlPoints.Min(x => x.ValueMirrored.X) * image.Width);
            var topY = (int)(profileControlPoints.Min(x => x.ValueMirrored.Y) * image.Height);
            var bottomY = (int)(profileControlPoints.Max(x => x.ValueMirrored.Y) * image.Height);

            leftX = leftX - 100 < 0 ? 0 : leftX - 100;          // ширину хз как определять, ой-вей
            topY = topY - 10 < 0 ? 0 : topY - 10;
            bottomY = bottomY + 10 > image.Height ? image.Height : bottomY + 10;
            var height = bottomY - topY;
            var faceRectangle = new Rectangle(leftX, topY, image.Width - leftX, height);

            var croppedImage = ImageEx.Crop(image, faceRectangle);
            for (var i = 0; i < profileControlPoints.Count; i++)            // смещаем все точки, чтобы учесть обрезанное
            {
                var point = profileControlPoints[i];
                var pointK = new Vector2(point.ValueMirrored.X * image.Width, point.ValueMirrored.Y * image.Height);        // по старой ширине-высоте

                pointK.X -= leftX;
                pointK.Y -= topY;

                profileControlPoints[i] = new MirroredHeadPoint(point.Value, new Vector2(pointK.X / (croppedImage.Width * 1f), pointK.Y / (croppedImage.Height * 1f)), false);    // и в новые
            }

            #endregion

            #region Поворот

            var xVector = new Vector2(1, 0);

            var vectorLeft = profileControlPoints[2].ValueMirrored - profileControlPoints[1].ValueMirrored; // из глаза рот
            vectorLeft = new Vector2(vectorLeft.X * croppedImage.Width, vectorLeft.Y * croppedImage.Height);
            vectorLeft.Normalize();
            var xDiff = xVector.X - vectorLeft.X;
            var yDiff = xVector.Y - vectorLeft.Y;
            var angleLeft = Math.Atan2(yDiff, xDiff);

            var vectorRight = profileControlPoints[2].Value - profileControlPoints[1].Value;
            vectorRight.Normalize();
            xDiff = xVector.X - vectorRight.X;
            yDiff = xVector.Y - vectorRight.Y;
            var angleRight = -Math.Atan2(yDiff, xDiff);

            var angleDiffRad = angleRight - angleLeft;
            var angleDiff = angleDiffRad * 180.0 / Math.PI;

            using (var ii = ImageEx.RotateImage(croppedImage, (float)angleDiff))
            {
                ProgramCore.Project.ProfileImage = new Bitmap(ii);
                SetTemplateImage(ProgramCore.Project.ProfileImage, false);
            }

            var center = new Vector2(ProgramCore.Project.ProfileImage.Width * 0.5f, ProgramCore.Project.ProfileImage.Height * 0.5f);
            var cosAngle = Math.Cos(angleDiffRad);
            var sinAngle = Math.Sin(angleDiffRad);
            for (var i = 0; i < profileControlPoints.Count; i++)            // смещаем все точки, чтобы учесть обрезанное
            {
                var point = profileControlPoints[i];
                var pointAbsolute = new Vector2(point.ValueMirrored.X * ProgramCore.Project.ProfileImage.Width, point.ValueMirrored.Y * ProgramCore.Project.ProfileImage.Height);        // по старой ширине-высоте

                var newPoint = pointAbsolute - center;
                newPoint = new Vector2((float)(newPoint.X * cosAngle - newPoint.Y * sinAngle),
                                           (float)(newPoint.Y * cosAngle + newPoint.X * sinAngle));
                newPoint += center;

                profileControlPoints[i] = new MirroredHeadPoint(point.Value, new Vector2(newPoint.X / (ProgramCore.Project.ProfileImage.Width * 1f), newPoint.Y / (ProgramCore.Project.ProfileImage.Height * 1f)), false);    // и в новые
            }

            ProgramCore.MainForm.ctrlRenderControl.InitializeProfileCamera(ModelAdaptParamProfile);

            #endregion

            var projectPath = Path.Combine(ProgramCore.Project.ProjectPath, "ProfileImage.jpg");
            ProgramCore.Project.ProfileImage.Save(projectPath);

            ControlPointsMode = ProfileControlPointsMode.UpdateRightLeft;
        }
        public void pictureTemplate_MouseUp(object sender, MouseEventArgs e)
        {
            startMousePoint = Vector2.Zero;
            if (e.Button == MouseButtons.Left)
            {
                headLastPoint = Vector2.Zero;
                switch (ProgramCore.MainForm.ctrlRenderControl.ScaleMode)
                {
                    case ScaleMode.Zoom:
                        tempOffsetPoint = Vector2.Zero;
                        break;
                    case ScaleMode.None:

                        #region Обычные режимы

                        switch (ProgramCore.MainForm.ctrlRenderControl.Mode)
                        {
                            case Mode.HeadAutodotsFirstTime:
                            case Mode.HeadAutodots:
                                {
                                    if (ProgramCore.Project.ShapeFlip != FlipType.None)
                                        return;

                                    if (!startMove && !dblClick)
                                    {
                                        if (!shiftKeyPressed)
                                            ProgramCore.MainForm.ctrlRenderControl.headController.AutoDots.ClearSelection();

                                        if (e.X >= MouthTransformed.X - HalfPointRectSize && e.X <= MouthTransformed.X + HalfPointRectSize && e.Y >= MouthTransformed.Y - HalfPointRectSize && e.Y <= MouthTransformed.Y + HalfPointRectSize)       // рот
                                            ProgramCore.MainForm.ctrlRenderControl.headController.SelectAutdotsMouth();
                                        else if (e.X >= LeftEyeTransformed.X - HalfPointRectSize && e.X <= LeftEyeTransformed.X + HalfPointRectSize && e.Y >= LeftEyeTransformed.Y - HalfPointRectSize && e.Y <= LeftEyeTransformed.Y + HalfPointRectSize)  // левый глаз
                                            ProgramCore.MainForm.ctrlRenderControl.headController.SelectAutodotsLeftEye();
                                        else if (e.X >= RightEyeTransformed.X - HalfPointRectSize && e.X <= RightEyeTransformed.X + HalfPointRectSize && e.Y >= RightEyeTransformed.Y - HalfPointRectSize && e.Y <= RightEyeTransformed.Y + HalfPointRectSize)  // правый глаз
                                            ProgramCore.MainForm.ctrlRenderControl.headController.SelectAutodotsRightEye();
                                        else if (e.X >= NoseTransformed.X - HalfPointRectSize && e.X <= NoseTransformed.X + HalfPointRectSize && e.Y >= NoseTransformed.Y - HalfPointRectSize && e.Y <= NoseTransformed.Y + HalfPointRectSize) // нос
                                            ProgramCore.MainForm.ctrlRenderControl.headController.SelectAutodotsNose();
                                        else if (e.X >= CentralFacePoint.X - HalfPointRectSize && e.X <= CentralFacePoint.X + HalfPointRectSize && e.Y >= CentralFacePoint.Y - HalfPointRectSize && e.Y <= CentralFacePoint.Y + HalfPointRectSize) // прямоугольник и выделение всех точек
                                        {
                                            if (RectTransformMode)
                                            {
                                                RectTransformMode = false;
                                                ProgramCore.MainForm.ctrlRenderControl.headController.AutoDots.ClearSelection();
                                            }
                                            else
                                            {
                                                RectTransformMode = true;
                                                UpdateUserCenterPositions(true, true);

                                                ProgramCore.MainForm.ctrlRenderControl.headController.SelectAutodotsFaceEllipse();
                                            }
                                        }
                                        else
                                            ProgramCore.MainForm.ctrlRenderControl.headController.UpdateAutodotsPointSelection(e.X, e.Y, true);
                                    }
                                    else
                                    {
                                        RecalcEyeMouthRect();

                                        if (ProgramCore.MainForm.ctrlRenderControl.Mode == Mode.HeadAutodots)
                                        {
                                            ProgramCore.MainForm.ctrlRenderControl.CalcReflectedBitmaps();
                                            ProgramCore.MainForm.ctrlRenderControl.headController.EndAutodots(false);
                                            ProgramCore.MainForm.ctrlRenderControl.ApplySmoothedTextures();

                                            for (var i = 0; i < ProgramCore.MainForm.ctrlRenderControl.headController.AutoDots.Count; i++)      // после слияние с ShapeDots. Проверить!
                                            {
                                                var p = ProgramCore.MainForm.ctrlRenderControl.headController.AutoDots[i];

                                                if (p.Selected)
                                                    ProgramCore.MainForm.ctrlRenderControl.autodotsShapeHelper.Transform(p.Value, i); // точка в мировых координатах
                                            }
                                        }
                                    }
                                }
                                break;
                            /*      case Mode.HeadShapedots:
                                      if (ProgramCore.Project.ShapeFlip != FlipType.None)
                                          return;

                                      if (!startMove && !dblClick)
                                      {
                                          if (!shiftKeyPressed)
                                              ProgramCore.MainForm.ctrlRenderControl.headController.ShapeDots.ClearSelection();

                                          if (e.X >= MouthTransformed.X - HalfPointRectSize && e.X <= MouthTransformed.X + HalfPointRectSize && e.Y >= MouthTransformed.Y - HalfPointRectSize && e.Y <= MouthTransformed.Y + HalfPointRectSize) // рот
                                              ProgramCore.MainForm.ctrlRenderControl.headController.SelectShapedotsMouth();
                                          else if (e.X >= LeftEyeTransformed.X - HalfPointRectSize && e.X <= LeftEyeTransformed.X + HalfPointRectSize && e.Y >= LeftEyeTransformed.Y - HalfPointRectSize && e.Y <= LeftEyeTransformed.Y + HalfPointRectSize) // левый глаз
                                              ProgramCore.MainForm.ctrlRenderControl.headController.SelectShapedotsLeftEye();
                                          else if (e.X >= RightEyeTransformed.X - HalfPointRectSize && e.X <= RightEyeTransformed.X + HalfPointRectSize && e.Y >= RightEyeTransformed.Y - HalfPointRectSize && e.Y <= RightEyeTransformed.Y + HalfPointRectSize) // правый глаз
                                              ProgramCore.MainForm.ctrlRenderControl.headController.SelectShapedotsRightEye();
                                          else if (e.X >= NoseTransformed.X - HalfPointRectSize && e.X <= NoseTransformed.X + HalfPointRectSize && e.Y >= NoseTransformed.Y - HalfPointRectSize && e.Y <= NoseTransformed.Y + HalfPointRectSize) // нос
                                              ProgramCore.MainForm.ctrlRenderControl.headController.SelectShapedotsNose();
                                          else if (e.X >= CentralFacePoint.X - HalfPointRectSize && e.X <= CentralFacePoint.X + HalfPointRectSize && e.Y >= CentralFacePoint.Y - HalfPointRectSize && e.Y <= CentralFacePoint.Y + HalfPointRectSize) // прямоугольник и выделение всех точек
                                          {
                                              if (RectTransformMode)
                                              {
                                                  RectTransformMode = false;
                                                  ProgramCore.MainForm.ctrlRenderControl.headController.ShapeDots.ClearSelection();
                                              }
                                              else
                                              {
                                                  RectTransformMode = true;
                                                  UpdateUserCenterPositions(true, true);

                                                  ProgramCore.MainForm.ctrlRenderControl.headController.SelectShapedotsFaceEllipse();
                                              }
                                          }
                                          else
                                              ProgramCore.MainForm.ctrlRenderControl.headController.UpdateShapedotsPointSelection(e.X, e.Y, true);
                                      }
                                      else
                                      {
                                          for (var i = 0; i < ProgramCore.MainForm.ctrlRenderControl.headController.ShapeDots.Count; i++)
                                          {
                                              var p = ProgramCore.MainForm.ctrlRenderControl.headController.ShapeDots[i];

                                              if (p.Selected)
                                                  ProgramCore.MainForm.ctrlRenderControl.autodotsShapeHelper.Transform(p.Value, i); // точка в мировых координатах
                                          }
                                      }
                                      break;*/
                            case Mode.HeadAutodotsLassoStart:
                                headAutodotsLassoPoints.Add(new Vector2(e.X, e.Y));
                                break;
                            /*    case Mode.HeadShapedotsLassoStart:
                                    headShapedotsLassoPoints.Add(new Vector2(e.X, e.Y));
                                    break;*/
                            case Mode.HeadLine:
                                {
                                    if (ProgramCore.Project.ShapeFlip != FlipType.None)
                                        return;

                                    if (ProgramCore.MainForm.HeadFront)
                                    {
                                        #region вид спереди

                                        if (!startMove && !dblClick)
                                        {
                                            #region Проверяем, начали ли что-то обводить линиями

                                            var firstTime = false;
                                            if (e.X >= MouthTransformed.X - 2.5 && e.X <= MouthTransformed.X + 2.5 && e.Y >= MouthTransformed.Y - 2.5 && e.Y <= MouthTransformed.Y + 2.5) // рот
                                            {
                                                if (ProgramCore.MainForm.ctrlRenderControl.HeadLineMode != MeshPartType.Lip)
                                                {
                                                    firstTime = true;
                                                    ProgramCore.MainForm.ctrlRenderControl.HeadLineMode = MeshPartType.Lip;
                                                }
                                            }
                                            else if (e.X >= LeftEyeTransformed.X - 2.5 && e.X <= LeftEyeTransformed.X + 2.5 && e.Y >= LeftEyeTransformed.Y - 2.5 && e.Y <= LeftEyeTransformed.Y + 2.5) // левый глаз
                                            {
                                                firstTime = true;
                                                ProgramCore.MainForm.ctrlRenderControl.HeadLineMode = MeshPartType.LEye;
                                            }
                                            else if (e.X >= RightEyeTransformed.X - 2.5 && e.X <= RightEyeTransformed.X + 2.5 && e.Y >= RightEyeTransformed.Y - 2.5 && e.Y <= RightEyeTransformed.Y + 2.5) // правый глаз
                                            {
                                                firstTime = true;
                                                ProgramCore.MainForm.ctrlRenderControl.HeadLineMode = MeshPartType.REye;
                                            }
                                            else if (e.X >= NoseTransformed.X - 2.5 && e.X <= NoseTransformed.X + 2.5 && e.Y >= NoseTransformed.Y - 2.5 && e.Y <= NoseTransformed.Y + 2.5) // нос
                                            {
                                                firstTime = true;
                                                ProgramCore.MainForm.ctrlRenderControl.HeadLineMode = MeshPartType.Nose;
                                            }
                                            else if (e.X >= CentralFacePoint.X - 2.5 && e.X <= CentralFacePoint.X + 2.5 && e.Y >= CentralFacePoint.Y - 2.5 && e.Y <= CentralFacePoint.Y + 2.5)
                                            {
                                                firstTime = true;
                                                ProgramCore.MainForm.ctrlRenderControl.HeadLineMode = MeshPartType.Head;
                                            }

                                            #endregion

                                            if (firstTime)          // выбираем режим линии
                                            {
                                                ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Clear();
                                                ProgramCore.MainForm.ctrlRenderControl.autodotsShapeHelper.ResetPoints(ProgramCore.MainForm.ctrlRenderControl.HeadLineMode);
                                            }
                                            else if (ProgramCore.MainForm.ctrlRenderControl.HeadLineMode != MeshPartType.None)          // добавляем новые точки
                                            {
                                                var point = new MirroredHeadPoint(headLastPointRelative, headLastPointRelative, false);
                                                point.UpdateWorldPoint();

                                                #region Проверка на количество линий и режим выделения

                                                if (ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Count > 1)
                                                {
                                                    var condition = false;
                                                    switch (ProgramCore.MainForm.ctrlRenderControl.HeadLineMode)
                                                    {
                                                        case MeshPartType.Lip:
                                                            if (ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Count > 2)
                                                                condition = true;
                                                            break;
                                                        default:
                                                            if (ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Count > 1)

                                                                condition = true;
                                                            break;
                                                    }

                                                    if (condition) // если ничего не выделили - начинаем рисовать новую линию. иначе уходим в режим выделения и таскания точек
                                                    {
                                                        if (!shiftKeyPressed)
                                                            ProgramCore.MainForm.ctrlRenderControl.headController.ClearPointsSelection();

                                                        if (ProgramCore.MainForm.ctrlRenderControl.headController.UpdatePointSelection(point.Value.X, point.Value.Y))
                                                            LineSelectionMode = true;
                                                        else
                                                        {
                                                            if (LineSelectionMode)
                                                            {
                                                                LineSelectionMode = false;
                                                                ProgramCore.MainForm.ctrlRenderControl.headController.ClearPointsSelection();
                                                                break;
                                                            }
                                                            else
                                                                ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Clear();
                                                        }
                                                    }
                                                }

                                                #endregion

                                                if (!LineSelectionMode)
                                                {
                                                    #region Добавляем новые точки линии

                                                    if (ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Count == 0)
                                                    {
                                                        var line = new HeadLine();
                                                        line.Add(point);
                                                        ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Add(line);
                                                    }
                                                    else
                                                    {
                                                        var currentLine = ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Last();
                                                        var hasIntersections = false;

                                                        if (currentLine.Count > 1) // проверка на пересечения линий
                                                        {
                                                            var lastPoint = currentLine.Last();

                                                            float ua, ub;
                                                            for (var i = currentLine.Count - 2; i >= 0; i--)
                                                            {
                                                                var pointA = currentLine[i];
                                                                var pointB = currentLine[i + 1];
                                                                if (AutodotsShapeHelper.GetUaUb(ref lastPoint.Value, ref point.Value, ref pointA.Value, ref pointB.Value, out ua, out ub))
                                                                {
                                                                    if (ua > 0 && ua < 1 && ub > 0 && ub < 1)
                                                                    {
                                                                        hasIntersections = true;
                                                                        break;
                                                                    }
                                                                }
                                                            }
                                                        }

                                                        var inAnotherPoint = false;
                                                        if (ProgramCore.MainForm.ctrlRenderControl.HeadLineMode == MeshPartType.Lip && ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Count == 2)
                                                        {
                                                            // ЭТо вторая линия губ
                                                            foreach (var lPoint in ProgramCore.MainForm.ctrlRenderControl.headController.Lines.First())
                                                                if (point.Value.X >= lPoint.Value.X - 0.25 && point.Value.X <= lPoint.Value.X + 0.25 && point.Value.Y >= lPoint.Value.Y - 0.25 && point.Value.Y <= lPoint.Value.Y + 0.25 && !currentLine.Contains(lPoint))
                                                                {
                                                                    if (currentLine.Count == 0)
                                                                        currentLine.Add(lPoint);
                                                                    else
                                                                    {
                                                                        currentLine.Add(lPoint);
                                                                        ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Add(new HeadLine());
                                                                    }
                                                                    inAnotherPoint = true;
                                                                    break;
                                                                }
                                                            if (currentLine.Count == 0) //первую точку добавляем всегда в пересечении с другой точкой.
                                                                inAnotherPoint = true;
                                                        }

                                                        // прочие случаи
                                                        if (!hasIntersections && !inAnotherPoint)
                                                        {
                                                            var firstPoint = currentLine.First();
                                                            if (point.Value.X >= firstPoint.Value.X - 0.25 && point.Value.X <= firstPoint.Value.X + 0.25 && point.Value.Y >= firstPoint.Value.Y - 0.25 && point.Value.Y <= firstPoint.Value.Y + 0.25)
                                                            {
                                                                currentLine.Add(firstPoint);
                                                                ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Add(new HeadLine());
                                                            }
                                                            else
                                                                currentLine.Add(point);
                                                        }
                                                    }

                                                    #endregion
                                                }
                                            }
                                        }

                                        #endregion
                                    }
                                    else
                                    {
                                        #region Вид сбоку

                                        if (isProfileSmoothing)
                                            return;

                                        if (!startMove && !dblClick)
                                        {
                                            var point = new MirroredHeadPoint(headLastPointRelative, headLastPointRelative, false);
                                            point.UpdateWorldPoint();

                                            #region Проверка на количество линий и режим выделения
                                            if (ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Count > 1) // если ничего не выделили - начинаем рисовать новую линию. иначе уходим в режим выделения и таскания точек
                                            {
                                                if (!shiftKeyPressed)
                                                    ProgramCore.MainForm.ctrlRenderControl.headController.ClearPointsSelection();

                                                if (ProgramCore.MainForm.ctrlRenderControl.headController.UpdatePointSelection(point.Value.X, point.Value.Y))
                                                    LineSelectionMode = true;
                                                else
                                                {
                                                    if (LineSelectionMode)
                                                    {
                                                        LineSelectionMode = false;
                                                        ProgramCore.MainForm.ctrlRenderControl.headController.ClearPointsSelection();
                                                        break;
                                                    }
                                                }
                                            }
                                            #endregion

                                            if (!LineSelectionMode)
                                            {
                                                #region Добавляем новые точки линии

                                                if (ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Count == 0)
                                                {
                                                    var line = new HeadLine();
                                                    line.Add(point);
                                                    ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Add(line);
                                                }
                                                else
                                                {
                                                    var currentLine = ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Last();
                                                    var hasIntersections = false;

                                                    if (currentLine.Count > 1) // проверка на пересечения линий
                                                    {
                                                        var lastPoint = currentLine.Last();

                                                        float ua, ub;
                                                        for (var i = currentLine.Count - 2; i >= 0; i--)
                                                        {
                                                            var pointA = currentLine[i];
                                                            var pointB = currentLine[i + 1];
                                                            if (AutodotsShapeHelper.GetUaUb(ref lastPoint.Value, ref point.Value, ref pointA.Value, ref pointB.Value, out ua, out ub))
                                                            {
                                                                if (ua > 0 && ua < 1 && ub > 0 && ub < 1)
                                                                {
                                                                    hasIntersections = true;
                                                                    break;
                                                                }
                                                            }
                                                        }
                                                    }

                                                    // прочие случаи
                                                    if (!hasIntersections)
                                                        currentLine.Add(point);
                                                }

                                                #endregion
                                            }
                                        }

                                        #endregion
                                    }

                                }
                                break;
                            case Mode.None:
                                {
                                    if (ProgramCore.MainForm.HeadProfile)
                                    {
                                        switch (ControlPointsMode)
                                        {
                                            case ProfileControlPointsMode.SetControlPoints:  // в профиле. расставляем опорные точки
                                                {
                                                    if (headLastPointRelative != Vector2.Zero)
                                                    {
                                                        profileControlPoints[profileControlPointIndex].ValueMirrored = headLastPointRelative;
                                                        ++profileControlPointIndex;

                                                        if (profileControlPointIndex == 4)
                                                        {
                                                            ControlPointsMode = ProfileControlPointsMode.MoveControlPoints;
                                                            profileControlPointIndex = 0;
                                                        }
                                                    }
                                                }
                                                break;
                                            case ProfileControlPointsMode.MoveControlPoints:  // выделяем и двигаем опорные точки
                                                {
                                                    if (!startMove && !dblClick)
                                                    {
                                                        if (!shiftKeyPressed)
                                                            foreach (var point in profileControlPoints)
                                                                point.Selected = false;

                                                        foreach (var point in profileControlPoints)
                                                        {
                                                            var pointK = new Vector2(point.ValueMirrored.X * ProgramCore.MainForm.ctrlTemplateImage.ImageTemplateWidth + ProgramCore.MainForm.ctrlTemplateImage.ImageTemplateOffsetX,
                                                                                     point.ValueMirrored.Y * ProgramCore.MainForm.ctrlTemplateImage.ImageTemplateHeight + ProgramCore.MainForm.ctrlTemplateImage.ImageTemplateOffsetY);
                                                            if (e.X >= pointK.X - 5 && e.X <= pointK.X + 5 && e.Y >= pointK.Y - 5 && e.Y <= pointK.Y + 5)
                                                            {
                                                                point.Selected = true;
                                                                break;
                                                            }
                                                        }
                                                    }
                                                }
                                                break;
                                            case ProfileControlPointsMode.UpdateRightLeft:  // выделяем и двигаем опорные точки
                                                {
                                                    if (!startMove && !dblClick)
                                                    {
                                                        if (!shiftKeyPressed)
                                                            foreach (var point in profileControlPoints)
                                                                point.Selected = false;

                                                        for (var i = 0; i < profileControlPoints.Count; i += 3)
                                                        {
                                                            var point = profileControlPoints[i];
                                                            var pointK = new Vector2(point.ValueMirrored.X * ProgramCore.MainForm.ctrlTemplateImage.ImageTemplateWidth + ProgramCore.MainForm.ctrlTemplateImage.ImageTemplateOffsetX,
                                                                                     point.ValueMirrored.Y * ProgramCore.MainForm.ctrlTemplateImage.ImageTemplateHeight + ProgramCore.MainForm.ctrlTemplateImage.ImageTemplateOffsetY);
                                                            if (e.X >= pointK.X - 5 && e.X <= pointK.X + 5 && e.Y >= pointK.Y - 5 && e.Y <= pointK.Y + 5)
                                                            {
                                                                point.Selected = true;
                                                                break;
                                                            }
                                                        }
                                                    }
                                                    else if (startMove)
                                                    {
                                                        UpdateProfileRectangle();
                                                    }
                                                }
                                                break;
                                        }
                                    }
                                }
                                break;
                        }

                        #endregion

                        break;
                }
            }

            moveRectIndex = -1;

            startMove = false;
            leftMousePressed = false;
            dblClick = false;
            headLastPointRelative = Vector2.Zero;
            headTempPoints.Clear();
            Cursor = Cursors.Arrow;
        }
        private void ctrlTemplateImage_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            if (e.KeyData == (Keys.A))
                ProgramCore.MainForm.ctrlRenderControl.headController.SelectAll();
            else if (e.KeyData == (Keys.D))
                ProgramCore.MainForm.ctrlRenderControl.headController.ClearPointsSelection();
            else if (e.KeyData == (Keys.ShiftKey | Keys.Shift))
                shiftKeyPressed = true;
            else if (e.KeyData == Keys.Enter)
            {
                switch (ProgramCore.MainForm.ctrlRenderControl.Mode)
                {
                    case Mode.HeadLine:
                        if (ProgramCore.MainForm.HeadProfile)
                        {
                            if (isProfileSmoothing)
                            {
                                isProfileSmoothing = false;
                                ProgramCore.MainForm.panelFront.UpdateProfileSmoothing(isProfileSmoothing);
                            }
                            else
                            if (ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Count == 2)
                            {
                                if (ProgramCore.MainForm.ctrlRenderControl.headController.AllPoints.Count > 3)
                                {
                                    foreach (var point in ProgramCore.MainForm.ctrlRenderControl.headController.AllPoints)
                                        point.UpdateWorldPoint();

                                    #region История (undo)

                                    Dictionary<Guid, MeshUndoInfo> undoInfo;
                                    ProgramCore.MainForm.ctrlRenderControl.headMeshesController.GetUndoInfo(out undoInfo);
                                    var isProfile = ProgramCore.MainForm.HeadProfile;
                                    var teInfo = isProfile ? ProgramCore.MainForm.ctrlRenderControl.autodotsShapeHelper.ShapeProfileInfo : ProgramCore.MainForm.ctrlRenderControl.autodotsShapeHelper.ShapeInfo;
                                    var historyElem = new HistoryHeadShapeLines(undoInfo, null, teInfo, isProfile);
                                    ProgramCore.MainForm.ctrlRenderControl.historyController.Add(historyElem);

                                    #endregion

                                    var userPoints = ProgramCore.MainForm.ctrlRenderControl.headController.AllPoints.Select(x => x.ValueMirrored).ToList();
                                    List<Vector2> pointsTop = new List<Vector2>();
                                    List<Vector2> pointsBottom = null;
                                    var lipsY = ProgramCore.MainForm.ctrlRenderControl.autodotsShapeHelper.GetLipsTopY();
                                    var prevPoint = Vector2.Zero;
                                    for (int i = 0; i < userPoints.Count; ++i)
                                    {
                                        var p = userPoints[i];
                                        var x = p.X * ProgramCore.MainForm.ctrlTemplateImage.ImageTemplateWidth + ProgramCore.MainForm.ctrlTemplateImage.ImageTemplateOffsetX;
                                        var y = p.Y * ProgramCore.MainForm.ctrlTemplateImage.ImageTemplateHeight + ProgramCore.MainForm.ctrlTemplateImage.ImageTemplateOffsetY;
                                        var point = ProgramCore.MainForm.ctrlRenderControl.camera.GetWorldPoint((int)x, (int)y,
                                            ProgramCore.MainForm.ctrlRenderControl.Width, ProgramCore.MainForm.ctrlRenderControl.Height, 1.0f).Zy;

                                        if (point.Y < lipsY && i > 0)
                                        {
                                            if (pointsBottom == null)
                                            {
                                                var tempPoint = point - prevPoint;
                                                var d = (point.Y - prevPoint.Y) / (prevPoint.Y - lipsY);
                                                var center = prevPoint + tempPoint * d;
                                                pointsTop.Add(center);
                                                pointsBottom = new List<Vector2>();
                                                pointsBottom.Add(center);
                                            }
                                            pointsBottom.Add(point);
                                        }
                                        else
                                        {
                                            prevPoint = point;
                                            pointsTop.Add(point);
                                        }
                                    }

                                    ProgramCore.MainForm.ctrlRenderControl.autodotsShapeHelper.Transform(MeshPartType.ProfileTop, pointsTop, Vector2.Zero);
                                    ProgramCore.MainForm.ctrlRenderControl.autodotsShapeHelper.Transform(MeshPartType.ProfileBottom, pointsBottom, Vector2.Zero);

                                    var th = new Thread(() =>
                                    {
                                        Thread.CurrentThread.IsBackground = true;
                                        ProgramCore.MainForm.ctrlRenderControl.headMeshesController.Smooth();
                                    });

                                    th.Start();
                                    while (th.IsAlive)
                                        ProgramCore.Progress("Please wait");

                                    ProfileSmoothing = new ProfileSmoothing(ProgramCore.MainForm.ctrlRenderControl.headMeshesController.RenderMesh, undoInfo);
                                }

                                foreach (var p in ProgramCore.MainForm.ctrlRenderControl.headMeshesController.RenderMesh.Parts)
                                    p.UpdateNormals();

                                ProgramCore.MainForm.ctrlRenderControl.headController.Lines.Clear();
                                //ProgramCore.MainForm.ctrlRenderControl.HeadLineMode = ProgramCore.MainForm.ctrlRenderControl.HeadLineMode == MeshPartType.ProfileTop ? MeshPartType.ProfileBottom : MeshPartType.ProfileTop;
                                ProgramCore.MainForm.ctrlRenderControl.UpdateProfileRectangle();
                                isProfileSmoothing = true;
                                ProgramCore.MainForm.panelFront.UpdateProfileSmoothing(isProfileSmoothing);
                            }
                            else
                                FinishLine();
                        }
                        else
                            FinishLine();
                        break;
                    case Mode.None:
                        if (ProgramCore.MainForm.HeadProfile)
                            switch (ControlPointsMode)
                            {
                                case ProfileControlPointsMode.MoveControlPoints:
                                    UpdateProfileImageByControlPoints();

                                    UpdateProfileRectangle();
                                    ProgramCore.MainForm.ctrlRenderControl.UpdateProfileRectangle();
                                    ControlPointsMode = ProfileControlPointsMode.UpdateRightLeft;
                                    break;
                                case ProfileControlPointsMode.UpdateRightLeft:
                                    UpdateProfileRectangle();
                                    foreach (var point in profileControlPoints)
                                        point.Selected = false;

                                    ControlPointsMode = ProfileControlPointsMode.None;
                                    break;
                            }

                        break;
                }
            }
        }