Esempio n. 1
0
        /// <summary>
        ///     Read DRL data replacing the drill positions with a custom pattern
        /// </summary>
        /// <param name="pattern">A pattern relative to it's origin 0,0</param>
        /// <param name="howmany">The number of elements to read</param>
        /// <returns>A list of geometries</returns>
        public List <IMarkGeometry> ReadAndReplaceWithCustom(List <IMarkGeometry> pattern, long howmany = -1)
        {
            var buffer = new List <IMarkGeometry>();

            BeginGetAll(
                (data) =>
            {
                if (data.Geometry is MarkGeometryPoint point)
                {
                    var transform = GeometricArithmeticModule.GetTranslationTransformationMatrix(point);

                    for (int i = 0; i < pattern.Count; i++)
                    {
                        var clone = (IMarkGeometry)pattern[i].Clone();
                        clone.Transform(transform);
                        buffer.Add(clone);
                    }
                }
                else
                {
                    buffer.Add(data.Geometry);
                }
            },
                howmany
                );

            return(buffer);
        }
Esempio n. 2
0
        /// <summary>
        ///     Use method to invert an input transform matrix about a given origin.
        ///     Could help when combining transformation for stages with inverted axis.
        /// </summary>
        /// <param name="taskHandler">An implementation of the process configuration tasks</param>
        /// <param name="parentTransform">The parent transform in the chain of transformations</param>
        /// <param name="transform">The input transformation</param>
        /// <param name="ctIn">A cancellation token</param>
        /// <returns>The input matrix flip about it's parent's transform</returns>
        public async Task <Matrix4x4> InvertTransform(IProcessConfigurationTasksHandler taskHandler, Matrix4x4 parentTransform, Matrix4x4 transform, CancellationToken ctIn)
        {
            var origin = new MarkGeometryPoint();

            origin.Transform(parentTransform);

            var inverts = await taskHandler.GetStageInverts(ctIn);

            return(GeometricArithmeticModule.CombineTransformations(
                       // flip about the base transform's origin
                       GeometricArithmeticModule.GetTranslationTransformationMatrix(
                           -origin.X, -origin.Y, -origin.Z
                           ),

                       // apply the next transform
                       transform,

                       // flip the next transform on the requested x-axis
                       GeometricArithmeticModule.GetScalingTransformationMatrix(
                           inverts.InvertX ? -1 : 1,
                           inverts.InvertY ? -1 : 1
                           ),

                       // translate back to the base transform's origin
                       GeometricArithmeticModule.GetTranslationTransformationMatrix(
                           origin.X, origin.Y, origin.Z
                           )
                       ));
        }
Esempio n. 3
0
        public static Matrix4x4 GetAlignmentTransform(MAlignmentType alignmentType, List <MarkGeometryPoint> estimatedPoints, List <MarkGeometryPoint> measuredPoints)
        {
            if (alignmentType == MAlignmentType.Type1 && measuredPoints?.Count > 0)
            {
                return(GeometricArithmeticModule.GetTranslationTransformationMatrix(
                           measuredPoints[0].X, measuredPoints[0].Y
                           ));
            }

            return(GeometricArithmeticModule.EstimateTransformationMatrixFromPoints(
                       estimatedPoints, measuredPoints
                       ));
        }
Esempio 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);
                }
            }
        }
Esempio n. 5
0
        public Matrix4x4 ToMatrix4x4()
        {
            return(GeometricArithmeticModule.CombineTransformations(
                       // apply scale
                       GeometricArithmeticModule.GetScalingTransformationMatrix(
                           ScaleX, ScaleY, ScaleZ
                           ),

                       // apply rotation - don't forget to convert degrees to radians
                       GeometricArithmeticModule.GetRotationTransformationMatrix(
                           GeometricArithmeticModule.ToRadians(RotationDegX),
                           GeometricArithmeticModule.ToRadians(RotationDegY),
                           GeometricArithmeticModule.ToRadians(RotationDegZ)
                           ),

                       // apply offset
                       GeometricArithmeticModule.GetTranslationTransformationMatrix(
                           OffsetX, OffsetY, OffsetZ
                           )
                       ));
        }
        // TODO: Implement mask angle align func
        //     1. The mask angle is measured directly by camera.
        //     2. The mask is rotated to compensate for the angle.
        //     3. The procedure continues until the angle is zero.

        public MVertex ConvertCADToMachineCoordinate(MVertex cadOrigin, MVertex pointOnCAD)
        {
            var transform = GeometricArithmeticModule.CombineTransformations(
                GeometricArithmeticModule.GetTranslationTransformationMatrix(
                    -cadOrigin.X, -cadOrigin.Y
                    ),
                GeometricArithmeticModule.GetRotationTransformationMatrix(
                    0, 0, Angle
                    ),
                GeometricArithmeticModule.GetTranslationTransformationMatrix(
                    OriginRelativeBEAM.X, OriginRelativeBEAM.Y
                    )
                );

            var result = Vector3.Transform(
                new Vector3((float)pointOnCAD.X, (float)pointOnCAD.Y, 0),
                transform
                );

            return(new MVertex(Inverts.X * result.X, Inverts.Y * result.Y));
        }
Esempio n. 7
0
        public bool SaveImage(string filePath)
        {
            var bitmap = new Bitmap(
                480, 480,
                PixelFormat.Format24bppRgb
                );

            var shader = new GeometryShader2D();

            shader.UpdateSettings(1, 1, Color.Red, Color.Green, Color.Transparent);

            shader.Reset(bitmap, Color.Black);

            var xScale = bitmap.Width / Boundary.Extents.Width;
            var yScale = bitmap.Height / Boundary.Extents.Height;

            // calculate transform
            var transformationMatrix = GeometricArithmeticModule.CombineTransformations(
                // centre geometries at origin before scaling
                GeometricArithmeticModule.GetTranslationTransformationMatrix(
                    -Boundary.Extents.Centre.X,
                    -Boundary.Extents.Centre.Y
                    ),
                // scale geometries to fit the target bitmap
                GeometricArithmeticModule.GetScalingTransformationMatrix(
                    xScale,
                    -yScale
                    ),
                // centre geometries in target bitmap
                GeometricArithmeticModule.GetTranslationTransformationMatrix(
                    0.5 * bitmap.Width,
                    0.5 * bitmap.Height
                    )
                );

            Draw(bitmap, shader, transformationMatrix);
            return(shader.WriteToFile(bitmap, filePath, PixelFormat.Format24bppRgb, 120, 120, GeometryShader2D.OptimisationSetting.Default));
        }
Esempio 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
                           )
                       ));
        }
Esempio n. 9
0
        public void Render()
        {
            _terminableTaskExecutor.CancelCurrentAndRun(
                (ctIn) =>
            {
                // reset shader
                MShader.Reset();

                if (_geometriesBuffer != null)
                {
                    int count   = 0;
                    var extents = GeometryExtents <double> .CreateDefaultDouble();
                    foreach (var layerName in _geometriesBuffer.Keys)
                    {
                        MShader.AddDefault(
                            _geometriesBuffer[layerName],
                            _colours[(count++) % _colours.Length]
                            );

                        extents = GeometryExtents <double> .Combine(
                            extents, GeometricArithmeticModule.CalculateExtents(_geometriesBuffer[layerName])
                            );
                    }

                    // overlay tiles
                    foreach (var tile in MTileSettings.ToTiles(TileSettings, extents))
                    {
                        MShader.AddDefault((MarkGeometryRectangle)tile, _tileColor);
                    }

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

                    // generate fiducial pattern
                    GenerateFiducialPattern(fiducialSize);

                    // get base transform
                    var baseTransform = GeometricArithmeticModule.GetTranslationTransformationMatrix(
                        extents.Centre.X, extents.Centre.Y
                        );

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

                        foreach (var geometry in _fiducialPattern)
                        {
                            var clone = (IMarkGeometry)geometry.Clone();
                            clone.Transform(transform);
                            MShader.AddDefault(clone, _fiducialColor);
                        }
                    }
                }

                // stop if new render is requested
                ctIn.ThrowIfCancellationRequested();

                MShader.Render();

                DrawingExtentsX = MShader.Width;
                DrawingExtentsY = MShader.Height;
                DrawingCount    = MShader.Count;
            }
                );
        }
Esempio n. 10
0
        public void Render()
        {
            _terminableTaskExecutor.CancelCurrentAndRun(
                (ctIn) =>
            {
                // reset shader
                MShader.Reset();

                if (_stlSlices != null)
                {
                    // add geometries
                    if (CurrentSlice >= 0 && CurrentSlice < _stlSlices.Count && _stlSlices[CurrentSlice] != null)
                    {
                        var stlSlice = _stlSlices[CurrentSlice];

                        // tiles
                        for (int i = 0; i < stlSlice.Tiles?.Count; i++)
                        {
                            MShader.AddDefault(stlSlice.Tiles[i], _tileColor);
                        }

                        // contours
                        for (int i = 0; i < stlSlice.ContourLines?.Count; i++)
                        {
                            MShader.AddDefault(stlSlice.ContourLines[i], MGLShader.Green);
                        }

                        // hatches
                        for (int i = 0; i < stlSlice.HatchLines?.Count; i++)
                        {
                            MShader.AddDefault(stlSlice.HatchLines[i], MGLShader.White);
                        }
                    }

                    // stop if new render is requested
                    ctIn.ThrowIfCancellationRequested();

                    // get base transform
                    var baseTransform = GeometricArithmeticModule.GetTranslationTransformationMatrix(
                        StlModelReferencePoint.X, StlModelReferencePoint.Y
                        );

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

                        foreach (var geometry in _fiducialPattern)
                        {
                            var clone = (IMarkGeometry)geometry.Clone();
                            clone.Transform(transform);
                            MShader.AddDefault(clone, _fiducialColor);
                        }
                    }
                }

                // stop if new render is requested
                ctIn.ThrowIfCancellationRequested();

                MShader.Render();
            }
                );
        }