//--------------------------------------------------------------------------------------------------

        void _Selection_SelectionChanged(SelectionManager selectionManager)
        {
            if (VisualShapes.EntityIsolationEnabled)
            {
                if (VisualShapes.GetIsolatedEntities().SymmetricExcept(selectionManager.SelectedEntities).Any())
                {
                    VisualShapes.SetIsolatedEntities(null);
                }
            }

            UpdateEditor();
        }
        //--------------------------------------------------------------------------------------------------

        void _Redraw()
        {
            if (Workspace.V3dViewer == null)
            {
                return;
            }

            Workspace.Viewports.ForEach(v =>
            {
                if (!v.AisAnimationCamera.IsStopped())
                {
                    v.AisAnimationCamera.UpdateTimer();
                    Workspace.NeedsRedraw = true;
                }
            });

            if (Workspace.NeedsRedraw)
            {
                VisualShapes.UpdateInvalidatedEntities();
                Workspace.Viewports.ForEach(v =>
                {
                    if (v.RenderMode == Viewport.RenderModes.HLR)
                    {
                        v.V3dView?.Update();
                    }
                });
                Workspace.V3dViewer.Redraw();
                Workspace.V3dViewer.RedrawImmediate();
                Workspace.NeedsRedraw = false;
            }
            else if (Workspace.NeedsImmediateRedraw)
            {
                Workspace.V3dViewer.RedrawImmediate();
                Workspace.NeedsImmediateRedraw = false;
            }
        }
        //--------------------------------------------------------------------------------------------------

        public void SelectByRectangle(int[] corners, bool includeTouched, ViewportController viewportController)
        {
            _MouseEventData.DetectedAisInteractives.Clear();
            _MouseEventData.DetectedEntities.Clear();
            _MouseEventData.DetectedShapes.Clear();

            if (Occt.Helper.Ais.PickFromContext(Workspace.AisContext, corners[0], corners[1], corners[2], corners[3], includeTouched,
                                                viewportController.Viewport.V3dView,
                                                _MouseEventData.DetectedAisInteractives, _MouseEventData.DetectedShapes) > 0)
            {
                var entities = _MouseEventData.DetectedAisInteractives.Select(detected => VisualShapes.GetVisibleEntity(detected)).Where(entity => entity != null);
                _MouseEventData.DetectedEntities.AddRange(entities);
            }
        }
        //--------------------------------------------------------------------------------------------------

        public void SelectByPolyline(List <ValueTuple <int, int> > pointList, bool includeTouched, ViewportController viewportController)
        {
            _MouseEventData.DetectedAisInteractives.Clear();
            _MouseEventData.DetectedEntities.Clear();
            _MouseEventData.DetectedShapes.Clear();

            if (Occt.Helper.Ais.PickFromContext(Workspace.AisContext, pointList, includeTouched,
                                                viewportController.Viewport.V3dView,
                                                _MouseEventData.DetectedAisInteractives, _MouseEventData.DetectedShapes) > 0)
            {
                var entities = _MouseEventData.DetectedAisInteractives.Select(detected => VisualShapes.GetVisibleEntity(detected)).Where(entity => entity != null);
                _MouseEventData.DetectedEntities.AddRange(entities);
            }
        }
        //--------------------------------------------------------------------------------------------------

        public void MouseMove(Point pos, ViewportController viewportController)
        {
            _LastMouseMovePosition           = pos;
            _LastMouseMoveViewportController = viewportController;

            Selection.Update();

            if (pos.X < 0 || pos.Y < 0)
            {
                // Position is out of bounds, reset highlighting
                Workspace.AisContext.MoveTo(Int32.MinValue, Int32.MinValue, viewportController.Viewport.V3dView, false);;
                Invalidate(true);
                return;
            }

            var status = Workspace.AisContext.MoveTo(Convert.ToInt32(pos.X), Convert.ToInt32(pos.Y), viewportController.Viewport.V3dView, false);

            Invalidate(true);

            if (status != AIS_StatusOfDetection.AIS_SOD_Error)
            {
                Pnt rawPoint;
                if (!viewportController.Viewport.ScreenToPoint(Convert.ToInt32(pos.X), Convert.ToInt32(pos.Y), out rawPoint))
                {
                    IsMouseEventDataValid = false;
                    IsCursorPositionValid = false;
                    return;
                }

                Pnt planePoint;
                if (!viewportController.Viewport.ScreenToPoint(Workspace.WorkingPlane, Convert.ToInt32(pos.X), Convert.ToInt32(pos.Y), out planePoint))
                {
                    IsMouseEventDataValid = false;
                    IsCursorPositionValid = false;
                }

                _LastDetectedInteractive = null;
                _LastDetectedOwner       = null;
                InteractiveEntity detectedEntity = null;
                TopoDS_Shape      detectedShape  = null;
                if (Workspace.AisContext.HasDetected())
                {
                    _LastDetectedInteractive = Workspace.AisContext.DetectedInteractive();
                    _LastDetectedOwner       = Workspace.AisContext.DetectedOwner();
                    detectedEntity           = VisualShapes.GetVisibleEntity(_LastDetectedInteractive);
                    detectedShape            = Occt.Helper.Ais.GetDetectedShapeFromContext(Workspace.AisContext);
                }

                _MouseEventData.Set(viewportController.Viewport, pos, rawPoint, planePoint, detectedEntity, _LastDetectedInteractive, detectedShape);
                IsMouseEventDataValid = true;

                CursorPosition        = planePoint;
                CursorPosition2d      = Workspace.WorkingPlane.Parameters(planePoint);
                IsCursorPositionValid = true;
                bool handled = false;

                if (CurrentTool != null)
                {
                    handled = CurrentTool.OnMouseMove(_MouseEventData);
                }

                if (_ToolActions.Any() && !handled)
                {
                    foreach (var toolAction in _ToolActions)
                    {
                        if (toolAction.OnMouseMove(_MouseEventData))
                        {
                            break;
                        }
                    }
                }

                if (_MouseEventData.ForceReDetection)
                {
                    Workspace.AisContext.MoveTo(Convert.ToInt32(pos.X), Convert.ToInt32(pos.Y), viewportController.Viewport.V3dView, false);
                }

                return;
            }

            IsMouseEventDataValid = false;
            IsCursorPositionValid = false;
        }