Exemplo n.º 1
0
        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);
            }
        }
Exemplo n.º 2
0
        private void grdViewPort_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            try
            {
                _isDraggingParts = false;
                _isDraggingSelectionBox = false;

                // Fire a ray at the mouse point
                Point clickPoint = e.GetPosition(grdViewPort);
                RayHitTestParameters clickRay;
                List<MyHitTestResult> hits = UtilityWPF.CastRay(out clickRay, clickPoint, grdViewPort, _camera, _viewport, true, null);

                // See if they clicked on an existing part
                DesignPart clickedItem = null;
                foreach (MyHitTestResult hit in hits.Where(o => o.ModelHit != null))		// skipping the dragshape hit
                {
                    #region Detect model hit

                    if (_selectedParts != null && !_selectedParts.IsLocked)
                    {
                        if (_selectedParts.IsModifierHit(hit.ModelHit.VisualHit))
                        {
                            // This is a modifier of the selected item (scale arrow or rotate ring)
                            _selectedParts.StartDraggingModifier(hit.ModelHit.VisualHit, clickPoint);		// if alt is pressed, I don't want to copy this, only when they drag the part around
                            _isDraggingParts = true;
                            return;
                        }
                    }

                    IEnumerable<DesignPart> candidates = null;
                    if (_isAllLayers)
                    {
                        candidates = _parts.SelectMany(o => o);
                    }
                    else
                    {
                        candidates = _parts[_currentLayerIndex];
                    }

                    var matches = candidates.Where(o => o.Model == hit.ModelHit.VisualHit);
                    if (matches.Count() == 1)
                    {
                        clickedItem = matches.First();
                        break;
                    }

                    #endregion
                }

                #region Update selected item

                // Update the currently selected item
                if (clickedItem != null && _selectedParts != null && _selectedParts.GetParts().Any(o => o == clickedItem))
                {
                    if (_isCtrlDown)
                    {
                        #region Deselect from selected parts

                        // Ctrl clicking a selected part will deselect it
                        _selectedParts.Remove(clickedItem);

                        if (_selectedParts.Count == 0)
                        {
                            ClearSelectedParts();
                        }

                        #endregion
                    }
                    else
                    {
                        #region Update click point

                        // They clicked on the same part, just update the points
                        _dragMouseDownClickRay = clickRay;
                        _dragMouseDownCenterRay = new RayHitTestParameters(_selectedParts.Position, clickRay.Direction);		//TODO: the ray through the center of the part really isn't parallel to the click ray (since the perspective camera sees in a cone)

                        #endregion
                    }
                }
                else if (clickedItem != null && _selectedParts != null && _isCtrlDown)
                {
                    #region Add to current selection

                    _selectedParts.Add(clickedItem);

                    // Remember the click location in case they start dragging
                    _dragMouseDownClickRay = clickRay;
                    _dragMouseDownCenterRay = new RayHitTestParameters(_selectedParts.Position, clickRay.Direction);		//TODO: the ray through the center of the part really isn't parallel to the click ray (since the perspective camera sees in a cone)

                    #endregion
                }
                else if (clickedItem == null && _isCtrlDown)
                {
                    // They missed any parts, but are making a ctrl+selectionbox.  Do nothing here and let mouseup take care of things
                }
                else
                {
                    #region Changing selection, or unselecting everything

                    ClearSelectedParts();

                    if (clickedItem != null)
                    {
                        // Select this part
                        _selectedParts = new SelectedParts(_viewport, _camera, _options);
                        _selectedParts.Add(clickedItem);

                        // Remember where they clicked
                        _dragMouseDownClickRay = clickRay;
                        _dragMouseDownCenterRay = new RayHitTestParameters(_selectedParts.Position, clickRay.Direction);		//TODO: the ray through the center of the part really isn't parallel to the click ray (since the perspective camera sees in a cone)

                        if (chkShowGuideLines.IsChecked.Value)
                        {
                            ShowGuideLines(chkShowGuideLinesAllLayers.IsChecked.Value);
                        }
                    }

                    #endregion
                }

                #endregion

                if (_isAltDown && _selectedParts != null)
                {
                    #region Clone part

                    List<UndoRedoAddRemove> undoItems = new List<UndoRedoAddRemove>();

                    // Make a copies of the selected parts
                    int partIndex = -1;
                    foreach (DesignPart clonedPart in _selectedParts.CloneParts())
                    {
                        partIndex++;

                        _viewport.Children.Add(clonedPart.Model);

                        if (clonedPart.GuideLines != null)
                        {
                            _viewport.Children.Add(clonedPart.GuideLines);
                        }

                        int layerIndex = _currentLayerIndex;
                        if (_isAllLayers)
                        {
                            List<DesignPart> origParts = _selectedParts.GetParts().ToList();
                            for (int cntr = 0; cntr < _parts.Count; cntr++)
                            {
                                if (_parts[cntr].Contains(origParts[partIndex]))
                                {
                                    layerIndex = cntr;
                                    break;
                                }
                            }
                        }

                        _parts[layerIndex].Add(clonedPart);

                        // Build undo item
                        undoItems.Add(new UndoRedoAddRemove(true, clonedPart, layerIndex));
                    }

                    // Store the undo items
                    if (undoItems.Count > 0)     // parts that need to be unique can't be cloned
                    {
                        AddNewUndoRedoItem(undoItems.ToArray());
                    }
                    else
                    {
                        ShowErrorMsg("Can't copy this part");
                    }

                    #endregion
                }

                if ((_selectedParts == null) || (clickedItem == null && _isCtrlDown))
                {
                    #region Start selection rectangle

                    if (!_isDraggingSelectionBox)
                    {
                        _isDraggingSelectionBox = true;
                        _selectionBoxMouseDownPos = e.GetPosition(grdViewPort);
                        grdViewPort.CaptureMouse();

                        // Initial placement of the drag selection box
                        Canvas.SetLeft(selectionBox, _selectionBoxMouseDownPos.X);
                        Canvas.SetTop(selectionBox, _selectionBoxMouseDownPos.Y);
                        selectionBox.Width = 0;
                        selectionBox.Height = 0;

                        // Make the drag selection box visible.
                        selectionBox.Visibility = Visibility.Visible;
                    }

                    #endregion
                }
                else if (clickedItem != null && _isCtrlDown)
                {
                    // They just deselected a part.  Don't drag, don't make a selection box
                }
                else
                {
                    _isDraggingParts = true;
                    _mouseDownDragPos = _selectedParts.Position;
                    _mouseDownDragOrientation = _selectedParts.Orientation.ToUnit();
                    _isSelectionDragDirty = false;
                }

                // Make sure the drag shape is current
                ChangeDragHitShape();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), _msgboxCaption, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
Exemplo n.º 3
0
        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]);
            }
        }
Exemplo n.º 4
0
        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);
            }
        }
Exemplo n.º 5
0
        private void ClearSelectedParts()
        {
            HideGuideLines();

            if (_selectedParts != null)
            {
                // Wipe out any selection visuals
                _selectedParts.Clear();
            }

            _selectedParts = null;
        }