private void Paste() { if (_clipboard == null || _clipboard.Length == 0) { return; } ClearSelectedParts(); List<DesignPart> pastedParts = new List<DesignPart>(); List<UndoRedoAddRemove> undoItems = new List<UndoRedoAddRemove>(); // Paste the parts foreach (DesignPart clipPart in _clipboard) { // Clone it DesignPart part = clipPart.Clone(); // Add it _viewport.Children.Add(part.Model); _parts[_currentLayerIndex].Add(part); // Remember this part undoItems.Add(new UndoRedoAddRemove(true, part, _currentLayerIndex)); pastedParts.Add(part); } // Store the undo items AddNewUndoRedoItem(undoItems.ToArray()); // Select the newly pasted parts _selectedParts = new SelectedParts(_viewport, _camera, _options); _selectedParts.AddRange(pastedParts); if (chkShowGuideLines.IsChecked.Value) { ShowGuideLines(chkShowGuideLinesAllLayers.IsChecked.Value); } }
private void grdViewPort_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { try { if (_isDraggingSelectionBox) { #region Selection Box // Release the mouse capture and stop tracking it. _isDraggingSelectionBox = false; grdViewPort.ReleaseMouseCapture(); // Hide the drag selection box. selectionBox.Visibility = Visibility.Collapsed; if (Math1D.IsNearZero(selectionBox.Width) || Math1D.IsNearZero(selectionBox.Height)) { // This is a miss, because the only way to start a selction box is to not click on anything return; } Point mouseUpPos = e.GetPosition(grdViewPort); // See if the part's centers are inside the rectangular solid. This way they are required to drag the box at least half way thru the part, but minor // touching will be ignored // Cast 4 rays Point topLeft = new Point(Canvas.GetLeft(selectionBox), Canvas.GetTop(selectionBox)); //Point bottomRight = new Point(Canvas.GetRight(selectionBox), Canvas.GetBottom(selectionBox)); // this is just returning NANs for bottom and right Point bottomRight = new Point(topLeft.X + selectionBox.Width, topLeft.Y + selectionBox.Height); var rayTopLeft = UtilityWPF.RayFromViewportPoint(_camera, _viewport, topLeft); var rayTopRight = UtilityWPF.RayFromViewportPoint(_camera, _viewport, new Point(bottomRight.X, topLeft.Y)); var rayBottomLeft = UtilityWPF.RayFromViewportPoint(_camera, _viewport, new Point(topLeft.X, bottomRight.Y)); var rayBottomRight = UtilityWPF.RayFromViewportPoint(_camera, _viewport, bottomRight); List<ITriangle> planes = new List<ITriangle>(); // visualizing this in sketchup is a life saver planes.Add(new Triangle(rayTopLeft.Origin, rayTopRight.Origin, rayTopLeft.Origin + rayTopLeft.Direction)); // top planes.Add(new Triangle(rayTopRight.Origin, rayBottomRight.Origin, rayTopRight.Origin + rayTopRight.Direction)); // right planes.Add(new Triangle(rayBottomRight.Origin, rayBottomLeft.Origin, rayBottomRight.Origin + rayBottomRight.Direction)); // bottom planes.Add(new Triangle(rayBottomLeft.Origin, rayTopLeft.Origin, rayBottomLeft.Origin + rayBottomLeft.Direction)); // left planes.Add(new Triangle(rayTopLeft.Origin, rayBottomRight.Origin, rayTopRight.Origin)); // selection box // Figure out which layers to look at IEnumerable<DesignPart> candidates = null; if (_isAllLayers) { candidates = _parts.SelectMany(o => o); } else { candidates = _parts[_currentLayerIndex]; } // Find all the parts inside this rectangular cone List<DesignPart> hitParts = candidates.Where(o => Math3D.IsInside_Planes(planes, o.Part3D.Position)).ToList(); if (_isCtrlDown && _selectedParts != null) { #region Ctrl+Select if (hitParts.Count > 0) { // Any of the hit parts that are currently in the selection should be removed. Any that aren't should be added List<DesignPart> origSelectedParts = _selectedParts.GetParts().ToList(); foreach (DesignPart hitPart in hitParts) { if (origSelectedParts.Contains(hitPart)) { _selectedParts.Remove(hitPart); } else { _selectedParts.Add(hitPart); } } if (_selectedParts.Count == 0) { ClearSelectedParts(); } } #endregion } else { #region Standard Select ClearSelectedParts(); // doesn't matter if there was a selection or not. A new one is needed if (hitParts.Count > 0) { // Create a selection, and put the hit parts in it _selectedParts = new SelectedParts(_viewport, _camera, _options); _selectedParts.AddRange(hitParts); } #endregion } // Update guidelines if (_selectedParts != null && chkShowGuideLines.IsChecked.Value) { ShowGuideLines(chkShowGuideLinesAllLayers.IsChecked.Value); } #endregion } else if (_isDraggingParts) { #region Finish moving selected parts _isDraggingParts = false; if (_selectedParts != null && _selectedParts.IsDraggingModifier) { _selectedParts.StopDraggingModifier(); } if (_selectedParts != null && _isSelectionDragDirty) { // They moved the selection, so store it in the undo list // Group the parts by layer SortedList<int, List<DesignPart>> selectedPartsByLayer = GetPartsByLayer(_selectedParts.GetParts().ToList()); // Build the undo items List<UndoRedoTransformChange> undoItems = new List<UndoRedoTransformChange>(); foreach (int layerIndex in selectedPartsByLayer.Keys) { undoItems.AddRange(selectedPartsByLayer[layerIndex].Select(o => new UndoRedoTransformChange(o.Part3D.Token, layerIndex) { Orientation = o.Part3D.Orientation, Position = o.Part3D.Position, Scale = o.Part3D.Scale })); } AddNewUndoRedoItem(undoItems.ToArray()); } #endregion } } catch (Exception ex) { MessageBox.Show(ex.ToString(), _msgboxCaption, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void SelectAllParts() { ClearSelectedParts(); // doesn't matter if there was a selection or not. A new one is needed if (!_isAllLayers && (_parts[_currentLayerIndex].Count == 0 || !((LayerRow)pnlLayers.Children[_currentLayerIndex + 1]).IsLayerVisible)) { // There are no parts in this layer return; } // Create a selection, and put the hit parts in it _selectedParts = new SelectedParts(_viewport, _camera, _options); if (_isAllLayers) { _selectedParts.AddRange(_parts.SelectMany(o => o)); } else { _selectedParts.AddRange(_parts[_currentLayerIndex]); } }