private void MouseDown(Viewport3D vp, ViewportEvent e) { if (!_currentTool.NoSelection()) { var vtxs = _currentTool.GetVerticesAtPoint(e.X, vp.Height - e.Y, vp); if (vtxs.Any()) { // Use the topmost vertex as the control point var vtx = vtxs.First(); // Mouse down on a point if (vtx.IsSelected && KeyboardState.Ctrl && _currentTool.ShouldDeselect(vtxs)) { // If the vertex is selected and ctrl is down, deselect the vertices vtxs.ForEach(x => x.IsSelected = false); } else { if (!vtx.IsSelected && !KeyboardState.Ctrl && _currentTool.ShouldDeselect(vtxs)) { // If we aren't clicking on a selected point and ctrl is not down, deselect the others Points.ForEach(x => x.IsSelected = false); // If this point is already selected, don't deselect others. This is the same behaviour as 2D selection. } vtxs.ForEach(x => x.IsSelected = true); } VertexSelectionChanged(); // Don't do other click operations return; } // Nothing clicked if (!KeyboardState.Ctrl) { // Deselect all the points if not ctrl-ing Points.ForEach(x => x.IsSelected = false); } } if (!_currentTool.No3DSelection()) { // Do selection var ray = vp.CastRayFromScreen(e.X, e.Y); var hits = Document.Map.WorldSpawn.GetAllNodesIntersectingWith(ray, true); var solid = hits .OfType <Solid>() .Select(x => new { Item = x, Intersection = GetIntersectionPoint(x, ray) }) .Where(x => x.Intersection != null) .OrderBy(x => (x.Intersection - ray.Start).VectorMagnitude()) .Select(x => x.Item) .FirstOrDefault(); if (solid != null) { if (solid.IsSelected && KeyboardState.Ctrl) { // deselect solid var select = new MapObject[0]; var deselect = new[] { solid }; Document.PerformAction("Deselect VM solid", new ChangeSelection(select, deselect)); } else if (!solid.IsSelected) { // select solid var select = new[] { solid }; var deselect = !KeyboardState.Ctrl ? Document.Selection.GetSelectedObjects() : new MapObject[0]; Document.PerformAction("Select VM solid", new ChangeSelection(select, deselect)); } // Don't do other click operations return; } } base.MouseDown(vp, e); }