コード例 #1
0
ファイル: DXFParser.cs プロジェクト: AdilGM/2DCAD
        private (string LayerName, MarkGeometryArc Arc) ParseArc(AdvancedLineStreamReader readerIn)
        {
            var(success, layerName) = ReadLayerName(readerIn, "AcDbCircle");

            if (success)
            {
                var result1 = readerIn.FindConsecutiveLines(
                    "100",
                    "AcDbCircle"
                    );

                if (!result1.Success)
                {
                    return(null, null);
                }
            }

            MarkGeometryPoint centrePoint = ReadPointFast(readerIn);

            // read radius 40
            readerIn.ReadLine();
            double radius = double.Parse(readerIn.ReadLine());

            var result2 = readerIn.FindConsecutiveLines(
                "100",
                "AcDbArc"
                );

            if (!result2.Success)
            {
                return(null, null);
            }

            // read angle 50
            readerIn.ReadLine();
            var startAngle = double.Parse(readerIn.ReadLine());

            // read angle 60
            readerIn.ReadLine();
            var endAngle = double.Parse(readerIn.ReadLine());

            var arc = new MarkGeometryArc(
                centrePoint,
                radius, // convert angle to radians
                GeometricArithmeticModule.ToRadians(startAngle),
                GeometricArithmeticModule.ToRadians(endAngle)
                );

            return(layerName, arc);
        }
コード例 #2
0
        private static (string Layer, IMarkGeometry Geometry) TryParseCircle(StreamReader readerIn)
        {
            string        layerName = null;
            IMarkGeometry geometry  = null;

            while (true)
            {
                var(found, line) = SkipUntil(readerIn, MatchLayerOrCircle);

                if (!found)
                {
                    break;
                }

                switch (MatchLayerOrCircle.Match(line).Value.Trim())
                {
                case "8":
                    layerName = readerIn.ReadLine();
                    break;

                case "AcDbCircle":
                    MarkGeometryPoint centre = TryParsePoint(readerIn);
                    if (centre == null)
                    {
                        throw new Exception("Failed to parse centre point of arc");
                    }

                    if (!SkipUntil(readerIn, MatchGroupCodeForRadius).Found)
                    {
                        throw new Exception("Failed to parse arc radius");
                    }

                    double radius = double.Parse(readerIn.ReadLine());

                    geometry = new MarkGeometryCircle(centre, radius)
                    {
                        LayerName = layerName
                    };
                    return(layerName, geometry);

                default:
                    throw new Exception($"Matched circle attribute is not supported: `{line}`");
                }
            }

            return(layerName, geometry);
        }
コード例 #3
0
ファイル: MSTLSlice.cs プロジェクト: AdilGM/2DCAD
        public MSTLSlice(List <MContourStructure> contours)
            : this()
        {
            NumberOfContours = contours.Count;

            MarkGeometryPoint lastPoint = null;

            foreach (var contourStructure in contours)
            {
                var(lines, minLineLength, perimeter) = GeometricArithmeticModule.GetLinesAndStatistics(
                    contourStructure.ToPoints()
                    );

                ContourLines.AddRange(
                    lines
                    );

                if (minLineLength < MinVectorLength)
                {
                    MinVectorLength = minLineLength;
                }

                _totalContourMarkDistance += perimeter;
                NumberOfJoints            += (lines.Count - 1);

                if (lines.Count > 0)
                {
                    if (lastPoint != null)
                    {
                        // measure and track the jump distance between the last contour and this
                        _totalContourJumpDistance += GeometricArithmeticModule.ABSMeasure(lastPoint, lines[0].StartPoint);
                    }

                    lastPoint = lines[0].StartPoint;
                }
            }

            _contourQuadTree = new ContourQuadTree(ContourLines);
            Extents          = GeometricArithmeticModule.CalculateExtents(ContourLines);
        }
コード例 #4
0
ファイル: MTileSettings.cs プロジェクト: AdilGM/2DCAD
        public static List <MTileDescription> ToTiles(MTileSettings tileSettings, GeometryExtents <double> extents)
        {
            var tiles = new List <MTileDescription>();

            double refWidth  = extents.Width + tileSettings.XPadding;
            double refHeight = extents.Height + tileSettings.YPadding;

            int nRows    = (int)Math.Ceiling(refHeight / tileSettings.YSize);
            int nColumns = (int)Math.Ceiling(refWidth / tileSettings.XSize);

            var _halfTileWidth  = 0.5 * tileSettings.XSize;
            var _halfTileHeight = 0.5 * tileSettings.YSize;
            var _centre         = extents.Centre - new MarkGeometryPoint(0.5 * (nColumns * tileSettings.XSize), 0.5 * (nRows * tileSettings.YSize));

            int counter = 0;

            for (int row = 0; row < nRows; row++)
            {
                for (int col = 0; col < nColumns; col++)
                {
                    var centrePoint = new MarkGeometryPoint(
                        (col * tileSettings.XSize) + _halfTileWidth,
                        (row * tileSettings.YSize) + _halfTileHeight
                        );

                    GeometricArithmeticModule.Translate(centrePoint, _centre.X + tileSettings.XOffset, _centre.Y + tileSettings.YOffset);

                    tiles.Add(
                        new MTileDescription(
                            counter++, centrePoint.X, centrePoint.Y, tileSettings.XSize, tileSettings.YSize
                            )
                        );
                }
            }

            return(tiles);
        }
コード例 #5
0
 protected static double[] ToDouble(MarkGeometryPoint point)
 {
     return(new double[] { point.X, point.Y });
 }
コード例 #6
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
                           )
                       ));
        }
コード例 #7
0
ファイル: MSTLSlice.cs プロジェクト: AdilGM/2DCAD
        public bool GenerateHatches(MHatchSettings settings)
        {
            HatchLines.Clear();
            _totalHatchesJumpDistance = 0;
            _totalHatchesMarkDistance = 0;

            var lines    = new List <MarkGeometryLine>();
            var angleRad = GeometricArithmeticModule.ToRadians(settings.Angle);

            var size    = Extents.Hypotenuse;
            var howmany = (int)Math.Ceiling(size / settings.Pitch);
            var yStart  = Extents.Centre.Y - (0.5 * size);

            // generate lines to calculate intersections for hatch
            if (settings.Style == HatchStyle.RASTER || settings.Style == HatchStyle.RASTER_GRID)
            {
                for (int i = 0; i < howmany; i++)
                {
                    double y = yStart + (i * settings.Pitch);

                    var line = new MarkGeometryLine(
                        new MarkGeometryPoint(
                            -size + Extents.Centre.X, y
                            ),
                        new MarkGeometryPoint(
                            size + Extents.Centre.X, y
                            )
                        );

                    // apply angular rotation
                    GeometricArithmeticModule.Rotate(line, 0, 0, angleRad, Extents.Centre.X, Extents.Centre.Y, Extents.Centre.Z);

                    lines.Add(line);
                }
            }
            else if (settings.Style == HatchStyle.SERPENTINE || settings.Style == HatchStyle.SERPENTINE_GRID)
            {
                for (int i = 0; i < howmany; i++)
                {
                    double y = yStart + (i * settings.Pitch);

                    if (i % 2 == 0)
                    {
                        var line = new MarkGeometryLine(
                            new MarkGeometryPoint(
                                -size + Extents.Centre.X, y
                                ),
                            new MarkGeometryPoint(
                                size + Extents.Centre.X, y
                                )
                            );

                        // apply angular rotation
                        GeometricArithmeticModule.Rotate(line, 0, 0, angleRad, Extents.Centre.X, Extents.Centre.Y, Extents.Centre.Z);

                        lines.Add(line);
                    }
                    else
                    {
                        var line = new MarkGeometryLine(
                            new MarkGeometryPoint(
                                size + Extents.Centre.X, y
                                ),
                            new MarkGeometryPoint(
                                -size + Extents.Centre.X, y
                                )
                            );

                        // apply angular rotation
                        GeometricArithmeticModule.Rotate(line, 0, 0, angleRad, Extents.Centre.X, Extents.Centre.Y, Extents.Centre.Z);

                        lines.Add(line);
                    }
                }
            }

            // duplicate lines if using grid
            var perpendicularAngleForGridLines = GeometricArithmeticModule.ToRadians(90);

            if (settings.Style == HatchStyle.RASTER_GRID || settings.Style == HatchStyle.SERPENTINE_GRID)
            {
                int startIndex = lines.Count - 1;
                for (int i = startIndex; i >= 0; i--)
                {
                    var ln = (MarkGeometryLine)lines[i].Clone();
                    GeometricArithmeticModule.Rotate(ln, 0, 0, perpendicularAngleForGridLines, Extents.Centre.X, Extents.Centre.Y, Extents.Centre.Z);

                    lines.Add(ln);
                }
            }

            // used to track jumps
            MarkGeometryPoint lastPoint = null;

            // generate hatch lines with extension
            for (int i = 0; i < lines.Count; i++)
            {
                List <MarkGeometryPoint> intersections = _contourQuadTree.Intersect(lines[i])?.ToList();

                if (intersections == null)
                {
                    continue;
                }

                int startIndex = (settings.Invert) ? 1 : 0;
                int endIndex   = intersections.Count - 1;

                while (startIndex < endIndex)
                {
                    var hatch = new MarkGeometryLine(
                        intersections[startIndex], intersections[startIndex + 1]
                        );

                    HatchLines.Add(hatch);

                    // increase mark and jump distance
                    if (lastPoint != null)
                    {
                        _totalHatchesJumpDistance += GeometricArithmeticModule.ABSMeasure2D(
                            lastPoint, hatch.StartPoint
                            );
                    }
                    _totalHatchesMarkDistance += hatch.Length;

                    lastPoint   = hatch.EndPoint;
                    startIndex += 2;
                }
            }

            return(true);
        }
コード例 #8
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
                           )
                       ));
        }
コード例 #9
0
        public TimeSpan EstimateProcessTime(MRecipeDeviceLayer layer)
        {
            const double kConst        = 0.000001;
            double       totalTaktTime = 0;

            IMarkParametersComplete processParams = FetchDXFParameters(layer);

            if (processParams == null)
            {
                return(TimeSpan.Zero);
            }

            int    numOfJoints  = 0;
            double jumpDistance = 0;
            double markDistance = 0;
            double minX         = double.MaxValue;
            double minY         = double.MaxValue;
            double maxX         = double.MinValue;
            double maxY         = double.MinValue;

            MarkGeometryPoint lastPosition = null;

            foreach (var geometry in FetchDXF(layer))
            {
                if (geometry is MarkGeometryPoint point)
                {
                    if (lastPosition != null)
                    {
                        jumpDistance += GeometricArithmeticModule.ABSMeasure2D(lastPosition, point);
                    }

                    markDistance += point.Perimeter;
                    lastPosition  = point;
                }
                else if (geometry is MarkGeometryLine line)
                {
                    if (lastPosition != null)
                    {
                        jumpDistance += GeometricArithmeticModule.ABSMeasure2D(lastPosition, line.StartPoint);
                    }

                    markDistance += line.Perimeter;
                    lastPosition  = line.EndPoint;
                }
                else if (geometry is MarkGeometryCircle circle)
                {
                    if (lastPosition != null)
                    {
                        jumpDistance += GeometricArithmeticModule.ABSMeasure2D(
                            lastPosition,
                            GeometricArithmeticModule.GetPointAtPosition(
                                circle, 0
                                )
                            );
                    }

                    markDistance += circle.Perimeter;
                    numOfJoints  += Math.Max(circle.VertexCount - 1, 0);
                    lastPosition  = GeometricArithmeticModule.GetPointAtPosition(circle, 1.0);
                }
                else if (geometry is MarkGeometryArc arc)
                {
                    if (lastPosition != null)
                    {
                        jumpDistance += GeometricArithmeticModule.ABSMeasure2D(lastPosition, arc.StartPoint);
                    }

                    markDistance += arc.Perimeter;
                    numOfJoints  += Math.Max(arc.VertexCount - 1, 0);
                    lastPosition  = arc.EndPoint;
                }
                else if (geometry is MarkGeometryPath path)
                {
                    if (lastPosition != null)
                    {
                        jumpDistance += GeometricArithmeticModule.ABSMeasure2D(lastPosition, path.StartPoint);
                    }

                    markDistance += path.Perimeter;
                    numOfJoints  += Math.Max(path.Points.Count - 1, 0);
                    lastPosition  = path.EndPoint;
                }

                if (geometry.Extents.MinX < minX)
                {
                    minX = geometry.Extents.MinX;
                }

                if (geometry.Extents.MinY < minY)
                {
                    minY = geometry.Extents.MinY;
                }

                if (geometry.Extents.MaxX > maxX)
                {
                    maxX = geometry.Extents.MaxX;
                }

                if (geometry.Extents.MaxY > maxY)
                {
                    maxY = geometry.Extents.MaxY;
                }
            }

            double taktTime = (
                (markDistance / processParams.MarkSpeed) +
                (jumpDistance / processParams.JumpSpeed) +
                (kConst * numOfJoints * (processParams.JumpDelay_us + processParams.MarkDelay - processParams.Nprev))
                );

            // account for repeats and stepping between tiles - convert millisecond to second
            totalTaktTime += ((taktTime * processParams.Passes) + (0.001 * layer.TileDescriptions.Count() * processParams.SettlingTimems));

            return(TimeSpan.FromSeconds(Math.Round(totalTaktTime, 4)));
        }
コード例 #10
0
 public IntersectionsBinaryTree(MarkGeometryPoint origin, MarkGeometryPoint point)
     : this(origin)
 {
     Insert(point);
 }
コード例 #11
0
 public static bool IsLesser(MarkGeometryPoint origin, MarkGeometryPoint p1, MarkGeometryPoint p2)
 {
     return(GeometricArithmeticModule.ABSMeasure2D(origin, p1) < GeometricArithmeticModule.ABSMeasure2D(origin, p2));
 }