Ejemplo n.º 1
0
 /// <summary>
 ///     Checking if the source item can be dropped into the target item
 /// </summary>
 /// <param name="sourceItem"></param>
 /// <param name="targetItem"></param>
 /// <returns></returns>
 private bool CheckDropTarget(MRecipeBaseNode sourceItem, MRecipeBaseNode targetItem)
 {
     return(
         sourceItem.GetType() == targetItem.GetType() ||
         sourceItem.Parent?.GetType() == targetItem.GetType()
         );
 }
Ejemplo n.º 2
0
 public void SelectNode(MRecipeBaseNode node)
 {
     if (
         node != null &&
         _lastSelectedNode != node
         )
     {
         _lastSelectedNode = node;
         RecipeItemSelectedCommand?.Execute(node);
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        ///     This event occurs when mouse is moved.Here first we check whether
        ///     left mouse button is pressed or not.Then check the distance mouse
        ///     moved if it moves outside the selected treeview item, then check
        ///     the drop effect if it's dragged (move) and then dropped over a
        ///     TreeViewItem (i.e. target is not null) then copy the selected
        ///     item in dropped item. In this event, you can put your desired
        ///     condition for dropping treeviewItem.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TreeView_MouseMove(object sender, MouseEventArgs e)
        {
            try
            {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    Point currentPosition = e.GetPosition(RecipeTreeView);

                    if (
                        (Math.Abs(currentPosition.X - _lastMouseDown.X) > 10.0) ||
                        (Math.Abs(currentPosition.Y - _lastMouseDown.Y) > 10.0)
                        )
                    {
                        _draggedItem = (MRecipeBaseNode)RecipeTreeView.SelectedItem;

                        if (RecipeTreeView != null)
                        {
                            var finalDropEffect = DragDrop.DoDragDrop(
                                RecipeTreeView,
                                RecipeTreeView.SelectedValue,
                                DragDropEffects.Move
                                );

                            //Checking target is not null and item is dragging(moving)
                            if (
                                (finalDropEffect == DragDropEffects.Move) && (_target != null)
                                )
                            {
                                // A Move drop was accepted - prevent drop on itself
                                if (_draggedItem != _target)
                                {
                                    // handle drop
                                    CopyItem(_draggedItem, _target);
                                    _target      = null;
                                    _draggedItem = null;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
        }
Ejemplo n.º 4
0
        public virtual void AddRecipeNode(MRecipe recipe, MRecipeBaseNode recipeNode)
        {
            if (recipe == null || recipeNode == null)
            {
                return;
            }

            var extents = GeometryExtents <double> .CreateDefaultDouble();

            MRecipe.BeginGetAllLayers_Parallel(recipeNode, (layer) =>
            {
                extents = GeometryExtents <double> .Combine(
                    extents,
                    AddLayer(recipe, layer)
                    );
            });

            // calculate size of fiducial relative to the node
            var fiducialSize = 0.025 * extents.Hypotenuse;

            // generate fiducial pattern
            GenerateFiducialPattern(fiducialSize);

            // get node's transform
            var parentsTransform = (recipeNode.Parent as MRecipeBaseNode)?.TransformInfo.ToMatrix4x4() ?? GeometricArithmeticModule.GetDefaultTransformationMatrix();

            // render fiducials in parent's reference frame
            foreach (var fiducial in recipeNode.Fiducials)
            {
                var transform = GeometricArithmeticModule.CombineTransformations(
                    GeometricArithmeticModule.GetTranslationTransformationMatrix(
                        fiducial.X, fiducial.Y, fiducial.Z
                        ),
                    parentsTransform
                    );

                foreach (var geometry in _fiducialPattern)
                {
                    var clone = (IMarkGeometry)geometry.Clone();
                    clone.Transform(transform);
                    AddDefault(clone, FiducialColor);
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        ///     This event occurs when an object is dropped on the drop target.
        ///     Here we check whether the dropped item is dropped on a
        ///     TreeViewItem or not. If yes, then set drop effect to none
        ///     and the target item into a variable. And then MouseMove
        ///     event completes the drag and drop operation.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TreeView_Drop(object sender, DragEventArgs e)
        {
            try
            {
                e.Effects = DragDropEffects.None;
                e.Handled = true;

                // Verify that this is a valid drop and then store the drop target
                var targetItem = GetNearestContainer(e.OriginalSource);
                if (targetItem != null && _draggedItem != null)
                {
                    _target   = targetItem;
                    e.Effects = DragDropEffects.Move;
                }
            }
            catch (Exception)
            {
            }
        }
Ejemplo n.º 6
0
        public void UpdateItemsSource()
        {
            if (RecipeItemsSource != null)
            {
                _lastSelectedNode = null;
                _mRecipe          = RecipeItemsSource;

                if (_undoRedoHelper?.IsPaused != true)
                {
                    _undoRedoHelper = new UndoRedoHelper <MRecipe>(ref _mRecipe);
                    MRecipe.BeginGetNodes(_mRecipe, (baseNode) => {
                        _undoRedoHelper.SaveStateOnPropertyChange(baseNode);
                    });

                    _undoRedoHelper.SaveState();
                }

                NotifyPropertyChanged(nameof(MRecipe));
            }
        }
Ejemplo n.º 7
0
        public IProcessConfigurationTasksHandler GetClosestConfigurationTasksHandler(MRecipeBaseNode startNode)
        {
            if (startNode is MRecipePlate plate)
            {
                return(_model.GetProcessConfigurationTaskHandler(
                           plate.Devices.FirstOrDefault()?.Layers.FirstOrDefault()?.TargetProcessMode
                           ));
            }
            else if (startNode is MRecipeDevice device)
            {
                return(_model.GetProcessConfigurationTaskHandler(
                           device.Layers.FirstOrDefault()?.TargetProcessMode
                           ));
            }
            else if (startNode is MRecipeDeviceLayer layer)
            {
                return(_model.GetProcessConfigurationTaskHandler(
                           layer.TargetProcessMode
                           ));
            }

            return(_model.GetProcessConfigurationTaskHandler((string)null));
        }
Ejemplo n.º 8
0
        public async Task <Matrix4x4> GetAbsoluteTransformFromStageOrigin(
            IProcessConfigurationTasksHandler taskHandler,
            ICamToBeam cam2Beam,
            MRecipe recipe,
            MRecipeBaseNode recipeNode,
            CancellationToken ctIn
            )
        {
            // firstly, find closest parent with fiducials
            var parent = recipeNode;

            while (
                parent != null &&
                parent.Fiducials.Count <= 0
                )
            {
                parent = parent.Parent as MRecipeBaseNode;
            }

            if (parent != null)
            {
                // recursion - get it's parent's transform
                var baseTransform = await GetAbsoluteTransformFromStageOrigin(
                    taskHandler, cam2Beam, recipe, parent.Parent as MRecipeBaseNode, ctIn
                    );

                var fiducialPoints = new List <MarkGeometryPoint>();
                var measuredPoints = new List <MarkGeometryPoint>();

                for (int i = 0; i < parent.Fiducials.Count; i++)
                {
                    var fiducial = parent.Fiducials[i];

                    if (!_cachedFiducials.ContainsKey(fiducial))
                    {
                        // estimate stage position
                        var stageLocation = new MarkGeometryPoint(
                            fiducial.X, fiducial.Y, fiducial.Z
                            );
                        stageLocation.Transform(baseTransform);

                        // goto estimated position
                        if (!await taskHandler.GotoXY(
                                stageLocation.X, stageLocation.Y, ctIn
                                ))
                        {
                            throw new Exception($"Failed to goto the estimated position; origin: {await taskHandler.GetStageOrigin(ctIn)}, fiducial: {(fiducial.X, fiducial.Y)} est: {stageLocation}");
                        }

                        // find and centre
                        {
                            if (!await cam2Beam.MoveBeamToCamOffset(ctIn))
                            {
                                throw new Exception($"Failed to move beam to cam offset");
                            }

                            if (!await taskHandler.MovetoCameraFocus(ctIn))
                            {
                                throw new Exception($"Failed to move camera to focus");
                            }

                            await taskHandler.SwitchCameraLedOn(ctIn);

                            // attempt to centre on fiducial
                            if (!await taskHandler.CentreOnVisibleObject(ctIn))
                            {
                                _logger.Info($"Failed to centre on fiducial");

                                // ask user to locate fiducials
                                Application.Current.Dispatcher.Invoke(
                                    () =>
                                {
                                    var fidVm              = taskHandler.GetNewFidFindViewModel();
                                    var inspectionDialog   = new InspectionWindow(fidVm, Application.Current.MainWindow);
                                    inspectionDialog.Owner = Application.Current.MainWindow;

                                    if (inspectionDialog.ShowDialog() != true)
                                    {
                                        throw new Exception("Failed to find fiducial");
                                    }

                                    // TODO : think about updating the machine's origin
                                }
                                    );
                            }

                            if (!await cam2Beam.MoveCamToBeamOffset(ctIn))
                            {
                                throw new Exception($"Failed to move camera to beam offset");
                            }
                        }

                        // read fiducial position
                        var(stgX, stgY, success) = await taskHandler.GetStageXY(ctIn);

                        if (!success)
                        {
                            throw new Exception("Failed to read the current stage position");
                        }

                        // update cache
                        _cachedFiducials[fiducial] = new MarkGeometryPoint(stgX, stgY);
                    }

                    // update measured points
                    fiducialPoints.Add(new MarkGeometryPoint(fiducial.X, fiducial.Y));
                    measuredPoints.Add(_cachedFiducials[fiducial]);
                }

                // calculate transform from measured fiducials
                var parentTransform = GeometricArithmeticModule.EstimateTransformationMatrixFromPoints(
                    fiducialPoints, measuredPoints
                    );

                return(GeometricArithmeticModule.CombineTransformations(
                           parentTransform,
                           await InvertTransform(
                               taskHandler,
                               parentTransform,
                               MRecipe.GetRelativeTransformFromParent(
                                   parent, recipeNode
                                   ),
                               ctIn
                               )
                           ));
            }

            var origin = await taskHandler.GetStageOrigin(ctIn);

            var stageOrigin = GeometricArithmeticModule.GetTranslationTransformationMatrix(
                origin.X, origin.Y
                );

            return(GeometricArithmeticModule.CombineTransformations(
                       stageOrigin,
                       await InvertTransform(
                           taskHandler,
                           stageOrigin,
                           MRecipe.GetRelativeTransform(
                               recipe, recipeNode
                               ),
                           ctIn
                           )
                       ));
        }
Ejemplo n.º 9
0
        /// <summary>
        ///     Insert source item into target
        /// </summary>
        /// <param name="sourceItem"></param>
        /// <param name="targetItem"></param>
        private void CopyItem(MRecipeBaseNode sourceItem, MRecipeBaseNode targetItem, bool deleteSource = true)
        {
            if (
                (sourceItem.GetType() == targetItem.GetType()) &&
                targetItem.Parent != null &&
                sourceItem.Parent != null
                )
            {
                if (targetItem.Parent is MRecipePlate)
                {
                    var data         = (sourceItem as MRecipeDevice);
                    var targetParent = (targetItem.Parent as MRecipePlate);
                    var sourceParent = (sourceItem.Parent as MRecipePlate);
                    int targetIndex  = targetParent.Devices.IndexOf(targetItem as MRecipeDevice);

                    // remove data from source and insert data into target
                    if (deleteSource)
                    {
                        sourceParent.Devices.Remove(data);
                    }
                    targetParent.Devices.Insert(targetIndex, data);

                    // update source's parent
                    sourceItem.Parent = targetItem.Parent;
                    lock (_undoRedoHelper)
                        _undoRedoHelper.SaveState();
                }
                else if (sourceItem.Parent is MRecipeDevice)
                {
                    var data         = (sourceItem as MRecipeDeviceLayer);
                    var targetParent = (targetItem.Parent as MRecipeDevice);
                    var sourceParent = (sourceItem.Parent as MRecipeDevice);
                    int targetIndex  = targetParent.Layers.IndexOf(targetItem as MRecipeDeviceLayer);

                    // remove data from source and insert data into target
                    if (deleteSource)
                    {
                        sourceParent.Layers.Remove(data);
                    }
                    targetParent.Layers.Insert(targetIndex, data);

                    // update source's parent
                    sourceItem.Parent = targetItem.Parent;
                    lock (_undoRedoHelper)
                        _undoRedoHelper.SaveState();
                }
                else if (sourceItem is MRecipePlate)
                {
                    var data         = (sourceItem as MRecipePlate);
                    var targetParent = (targetItem.Parent as MRecipe);
                    var sourceParent = (sourceItem.Parent as MRecipe);
                    int targetIndex  = targetParent.Plates.IndexOf(targetItem as MRecipePlate);

                    // remove data from source and insert data into target
                    if (deleteSource)
                    {
                        sourceParent.Plates.Remove(data);
                    }
                    targetParent.Plates.Insert(targetIndex, data);

                    // update source's parent
                    sourceItem.Parent = targetItem.Parent;
                    lock (_undoRedoHelper)
                        _undoRedoHelper.SaveState();
                }

                //var response = MessageBox.Show(
                //    $"Would you like to move {sourceItem.Tag} into position" +  + "", "", MessageBoxButton.YesNo
                //);
            }
            else if (
                (sourceItem.Parent?.GetType() == targetItem.GetType())
                )
            {
                if (targetItem is MRecipePlate)
                {
                    var data         = (sourceItem as MRecipeDevice);
                    var targetParent = (targetItem as MRecipePlate);
                    var sourceParent = (sourceItem.Parent as MRecipePlate);

                    // remove data from source and add data to target
                    if (deleteSource)
                    {
                        sourceParent.Devices.Remove(data);
                    }
                    targetParent.Devices.Add(data);

                    // update source's parent
                    sourceItem.Parent = targetParent;
                    lock (_undoRedoHelper)
                        _undoRedoHelper.SaveState();
                }
                else if (targetItem is MRecipeDevice)
                {
                    var data         = (sourceItem as MRecipeDeviceLayer);
                    var targetParent = (targetItem as MRecipeDevice);
                    var sourceParent = (sourceItem.Parent as MRecipeDevice);

                    // remove data from source and add data to target
                    if (deleteSource)
                    {
                        sourceParent.Layers.Remove(data);
                    }
                    targetParent.Layers.Add(data);

                    // update source's parent
                    sourceItem.Parent = targetParent;
                    lock (_undoRedoHelper)
                        _undoRedoHelper.SaveState();
                }
            }
        }
Ejemplo n.º 10
0
        public MRecipeTreeViewUserControl()
        {
            InitializeComponent();

            UndoCommand = new DelegateCommand(
                () =>
            {
                Undo();
            }
                );

            RedoCommand = new DelegateCommand(
                () =>
            {
                Redo();
            }
                );

            //ItemSelectedCommand = new DelegateCommand<MRecipeBaseNode>(
            //    (selectedItem)=> {
            //        NotifyPropertyChanged(nameof(CanPasteItem));
            //        NotifyPropertyChanged(nameof(CanCreateChild));

            //        // run receipe selected callback on a different thread
            //        SelectNode(selectedItem);
            //    }
            //);

            RightClickContextMenuCommand = new DelegateCommand <MRecipeBaseNode>(
                (selectedItem) => {
                _lastSelectedNode = selectedItem;
                NotifyPropertyChanged(nameof(CanPasteItem));
                NotifyPropertyChanged(nameof(CanCreateChild));
            }
                );

            NewItemCommand = new DelegateCommand <MRecipeBaseNode>(
                (node) => {
                if (node is MRecipePlate plate)
                {
                    (node.Parent as MRecipe).Plates.Add(
                        new MRecipePlate()
                    {
                        Parent = node.Parent
                    }
                        );
                }
                else if (node is MRecipeDevice device)
                {
                    (node.Parent as MRecipePlate).Devices.Add(
                        new MRecipeDevice()
                    {
                        Parent = node.Parent
                    }
                        );
                }
                else if (node is MRecipeDeviceLayer layer)
                {
                    (node.Parent as MRecipeDevice).Layers.Add(
                        new MRecipeDeviceLayer()
                    {
                        Parent = node.Parent
                    }
                        );
                }
                else
                {
                    return;
                }

                lock (_undoRedoHelper)
                    _undoRedoHelper.SaveState();
                SelectNode(node);
            }
                );

            CreateChildItemCommand = new DelegateCommand <MRecipeBaseNode>(
                (node) => {
                if (node is MRecipePlate plate)
                {
                    plate.Devices.Add(
                        new MRecipeDevice()
                    {
                        Parent = node
                    }
                        );
                }
                else if (node is MRecipeDevice device)
                {
                    device.Layers.Add(
                        new MRecipeDeviceLayer()
                    {
                        Parent = node
                    }
                        );
                }
                else
                {
                    return;
                }

                lock (_undoRedoHelper)
                    _undoRedoHelper.SaveState();

                SelectNode(node);
            }
                );

            DuplicateItemCommand = new DelegateCommand <MRecipeBaseNode>(
                (node) => {
                CopyItem((MRecipeBaseNode)node.Clone(), (MRecipeBaseNode)node, false);

                lock (_undoRedoHelper)
                    _undoRedoHelper.SaveState();

                SelectNode(node);
            }
                );

            DuplicateItemAsArrayCommand = new DelegateCommand <MRecipeBaseNode>(
                (node) => {
                var dialog   = new PasteAsArrayDialog();
                dialog.Owner = Application.Current.MainWindow;
                if (dialog.ShowDialog() != true)
                {
                    return;
                }

                try
                {
                    lock (_undoRedoHelper)
                        _undoRedoHelper?.Pause();

                    MArrayInfo.BeginGetAll(dialog.ArrayInfo, (positionInfo) => {
                        var clone = (MRecipeBaseNode)node.Clone();
                        clone.TransformInfo.OffsetX += positionInfo.XInfo.Offset;
                        clone.TransformInfo.OffsetY += positionInfo.XInfo.Offset;
                        clone.TransformInfo.OffsetZ += positionInfo.XInfo.Offset;

                        CopyItem(clone, node, false);
                    });
                }
                finally
                {
                    lock (_undoRedoHelper)
                    {
                        _undoRedoHelper?.Resume();
                        _undoRedoHelper.SaveState();
                    }
                }

                SelectNode(node);
            }
                );

            CopyItemCommand = new DelegateCommand <MRecipeBaseNode>(
                (node) => {
                if (node != null)
                {
                    _copiedItem = node;
                }
            }
                );

            PasteItemCommand = new DelegateCommand <MRecipeBaseNode>(
                (node) => {
                if (node == null)
                {
                    return;
                }

                // update selected node
                _lastSelectedNode = node;
                if (CanPasteItem == false)
                {
                    return;
                }

                CopyItem((MRecipeBaseNode)_copiedItem.Clone(), _lastSelectedNode, false);
                SelectNode(node);
            }
                );

            PasteItemAsArrayCommand = new DelegateCommand <MRecipeBaseNode>(
                (node) => {
                if (node == null)
                {
                    return;
                }

                // update selected node
                _lastSelectedNode = node;
                if (CanPasteItem == false)
                {
                    return;
                }

                var dialog   = new PasteAsArrayDialog();
                dialog.Owner = Application.Current.MainWindow;
                if (dialog.ShowDialog() != true)
                {
                    return;
                }

                var selectedNode = _lastSelectedNode;

                try
                {
                    lock (_undoRedoHelper)
                        _undoRedoHelper?.Pause();

                    for (int x = 0; x < dialog.ArrayInfo.NumX; x++)
                    {
                        for (int y = 0; y < dialog.ArrayInfo.NumY; y++)
                        {
                            for (int z = 0; z < dialog.ArrayInfo.NumZ; z++)
                            {
                                var clone = (MRecipeBaseNode)_copiedItem.Clone();
                                clone.TransformInfo.OffsetX += x * dialog.ArrayInfo.PitchX;
                                clone.TransformInfo.OffsetY += y * dialog.ArrayInfo.PitchY;
                                clone.TransformInfo.OffsetZ += z * dialog.ArrayInfo.PitchZ;

                                CopyItem(clone, selectedNode, false);
                            }
                        }
                    }
                }
                finally
                {
                    lock (_undoRedoHelper)
                    {
                        _undoRedoHelper?.Resume();
                        _undoRedoHelper.SaveState();
                    }
                }

                SelectNode(node);
            }
                );

            DeleteItemCommand = new DelegateCommand <MRecipeBaseNode>(
                (node) => {
                if (node is MRecipePlate plate)
                {
                    (node.Parent as MRecipe).Plates.Remove(
                        plate
                        );
                }
                else if (node is MRecipeDevice device)
                {
                    (node.Parent as MRecipePlate).Devices.Remove(
                        device
                        );
                }
                else if (node is MRecipeDeviceLayer layer)
                {
                    (node.Parent as MRecipeDevice).Layers.Remove(
                        layer
                        );
                }
                else
                {
                    return;
                }

                lock (_undoRedoHelper)
                    _undoRedoHelper.SaveState();

                SelectNode(node);
            }
                );
        }
Ejemplo n.º 11
0
        public async Task <Matrix4x4> GetAbsoluteTransform(MRecipeBaseNode node, Matrix4x4 parentTransform, CancellationToken ctIn)
        {
            if (parentTransform == null)
            {
                parentTransform = GeometricArithmeticModule.GetDefaultTransformationMatrix();
            }

            // node has no fiducials, hences it's position
            // is relative to its parent
            if (node.Fiducials.Count <= 0)
            {
                return(GeometricArithmeticModule.CombineTransformations(
                           parentTransform,
                           node.TransformInfo.ToMatrix4x4()
                           ));
            }

            // attempt to retrieve tasksHandler; handles process specific stage motion
            // camera, find n centre, etc.
            IProcessConfigurationTasksHandler tasksHandler = GetClosestConfigurationTasksHandler(node);

            if (tasksHandler == null)
            {
                throw new Exception("Failed to retrieve a Task Handler for the closest process mode");
            }

            // buffer to store estimated and measured fiducials
            var estimatedPoints = new List <MarkGeometryPoint>();
            var measuredPoints  = new List <MarkGeometryPoint>();

            for (int i = 0; i < node.Fiducials.Count; i++)
            {
                var estimatedPosition = new MarkGeometryPoint(
                    node.Fiducials[i].X, node.Fiducials[i].Y
                    );

                // transform to parents space
                estimatedPosition.Transform(parentTransform);
                estimatedPoints.Add(estimatedPosition);

                // move camera to position
                await tasksHandler.FocusCameraAtXY(
                    estimatedPosition.X,
                    estimatedPosition.Y,
                    ctIn
                    );

                // get measured position
                var results = await tasksHandler.TakeMeasurement();

                // handle results not found
                if (!results.Found)
                {
                    throw new Exception("Failed to find fiducial");
                }

                // store measured point
                measuredPoints.Add(
                    new MarkGeometryPoint(
                        results.Position.X,
                        results.Position.Y
                        )
                    );
            }

            return(GeometricArithmeticModule.CombineTransformations(
                       parentTransform,
                       MAlignmentCalculator.GetAlignmentTransform(
                           node.AlignmentType,
                           estimatedPoints,
                           measuredPoints
                           )
                       ));
        }