/// <summary> /// Saves the contours and hatches in layers corresponding to its tile /// </summary> /// <param name="outputDirectory"></param> /// <param name="outputName"></param> /// <returns></returns> public bool ExportAsDXF(string outputDirectory, string outputName) { var outputFilePath = Path.Combine(outputDirectory, outputName); var document = new DxfDocument(new HeaderVariables()); // combine geometries var geometries = HatchLines.Concat(ContourLines).ToArray(); // clip geometries in tiles and results to dxf layer for (int i = 0; i < Tiles.Count; i++) { for (int j = 0; j < geometries.Length; j++) { var results = GeometricArithmeticModule.ClipGeometry( geometries[j], Tiles[i] ); for (int k = 0; k < results?.Count; k++) { document.AddEntity( results[k].GetAsDXFEntity( $"Tile {i}" ) ); } } } document.Save(outputFilePath); return(File.Exists(outputFilePath)); }
public override void Draw2D(IMarkGeometryVisualizer2D view, bool shouldShowVertex) { view.Draw2D( GeometricArithmeticModule.ToLines(Points), shouldShowVertex ); }
public void GenerateRecipeInfo() { RecipeInfo.Clear(); int index = 0; MRecipe.BeginGetAllLayers(RecipeVm, (layer) => { if (layer.TileDescriptions.Count() <= 0) { layer.GenerateTileDescriptionsFromSettings( GeometricArithmeticModule.CalculateExtents(FetchDXF(layer)) ); } var info = new RecipeProcessEntityInfo() { Index = index++, Layer = layer, EstimatedTime = EstimateProcessTime(layer) }; RecipeInfo.Add(info); }); // fetch recipe's count and extents (RecipeGeometriesCount, RecipeExtents) = MRecipe.CalculateExtents(RecipeVm); }
public MarkGeometrySpline(Spline spline) : base() { FitPoints = spline.FitPoints.ConvertAll(x => new MarkGeometryPoint(x)); ControlPoints = new List <SplineVertex>(spline.ControlPoints).ConvertAll(x => new MarkGeometryPoint(x.Position));; Knots = spline.Knots.ToList(); IsPeriodic = spline.IsPeriodic; IsClosed = spline.IsClosed; Degree = spline.Degree; // TODO : Remove var polyline = spline.ToPolyline(spline.ControlPoints.Count * 5); Points.AddRange( polyline.Vertexes.Select(v => new MarkGeometryPoint(v.Position)) ); if ( polyline.IsClosed && GeometricArithmeticModule.Compare(StartPoint, EndPoint, ClosureTolerance) != 0) { Points.Add((MarkGeometryPoint)StartPoint.Clone()); } // END Remove Update(); }
public virtual void AddLayerTiles(MRecipe recipe, MRecipeDeviceLayer layer) { // get layer's transform var transform = MRecipe.GetRelativeTransform(recipe, layer); // update layer's tile info if (layer.TileDescriptions.Count <= 0) { layer.GenerateTileDescriptionsFromSettings( (patternFilePath) => { return(GeometricArithmeticModule.CalculateExtents( _fetchDxfFunc(patternFilePath) )); } ); } // render tiles for (int i = 0; i < layer.TileDescriptions.Count; i++) { var tile = (MarkGeometryRectangle)layer.TileDescriptions[i]; tile.Transform(transform); AddDefault(tile, TileColor); } }
/// <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 ) )); }
/// <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); }
public bool GenerateTiles(MTileSettings settings) { // delete previous tiles Tiles.Clear(); double refWidth = Extents.Width + settings.XPadding; double refHeight = Extents.Height + settings.YPadding; int nRows = (int)Math.Ceiling(refHeight / settings.YSize); int nColumns = (int)Math.Ceiling(refWidth / settings.XSize); var _halfTileWidth = 0.5 * settings.XSize; var _halfTileHeight = 0.5 * settings.YSize; var _centre = Extents.Centre - new MarkGeometryPoint(0.5 * (nColumns * settings.XSize), 0.5 * (nRows * settings.YSize)); for (int row = 0; row < nRows; row++) { for (int col = 0; col < nColumns; col++) { var centrePoint = new MarkGeometryPoint( (col * settings.XSize) + _halfTileWidth, (row * settings.YSize) + _halfTileHeight ); GeometricArithmeticModule.Translate(centrePoint, _centre.X + settings.XOffset, _centre.Y + settings.YOffset); Tiles.Add(new MarkGeometryRectangle(centrePoint, settings.XSize, settings.YSize)); } } return(true); }
public void Add(MarkGeometryPath path) { AddRange(GeometricArithmeticModule.ToLines(path.Points)); // doesn't call Update(); because it is already called by the above method AddGeometry // change if this is no longer the case }
public override void Transform(Matrix4x4 transformationMatrixIn) { CentrePoint.Transform(transformationMatrixIn); StartPoint.Transform(transformationMatrixIn); Radius = GeometricArithmeticModule.ABSMeasure(StartPoint, CentrePoint); Update(); }
public MarkGeometryPoint GetClosestOrigin() { return(new MarkGeometryPoint( GeometricArithmeticModule.Constrain(0, (double)(MinX as double?), (double)(MaxX as double?)), GeometricArithmeticModule.Constrain(0, (double)(MinY as double?), (double)(MaxY as double?)), GeometricArithmeticModule.Constrain(0, (double)(MinZ as double?), (double)(MaxZ as double?)) )); }
public ContourQuadTree(IEnumerable <MVertex> vertices) { Create( GeometricArithmeticModule.ToLines( vertices.Select(v => new MarkGeometryPoint(v.X, v.Y)).ToArray() ) ); }
public void GenerateView() { for (int i = 0; i < VertexCount; i++) { Points.Add(GeometricArithmeticModule.GetPointAtPosition( StartPoint, EndPoint, ControlPoint_1, ControlPoint_2, i / (double)(VertexCount - 1)) ); } }
public bool Insert(MarkGeometryLine line) { if ( !( GeometricArithmeticModule.IsWithin2D(line.StartPoint, Boundary.Extents) && GeometricArithmeticModule.IsWithin2D(line.EndPoint, Boundary.Extents) ) ) { return(false); } // ensure quads exist if (!ChildrenExists) { var radius = 0.5 * SubSize; NorthWest = new ContourQuadTree( Boundary.Extents.MinX + radius, // west Boundary.Extents.MaxY - radius, // north SubSize ); NorthEast = new ContourQuadTree( Boundary.Extents.MaxX - radius, // east Boundary.Extents.MaxY - radius, // north SubSize ); SouthWest = new ContourQuadTree( Boundary.Extents.MinX + radius, // west Boundary.Extents.MinY + radius, // south SubSize ); SouthEast = new ContourQuadTree( Boundary.Extents.MaxX - radius, // east Boundary.Extents.MinY + radius, // south SubSize ); ChildrenExists = true; } if ( (line.Length <= MinSize) || !( NorthWest.Insert(line) || NorthEast.Insert(line) || SouthWest.Insert(line) || SouthEast.Insert(line) ) ) { Segments.Add(line); } return(true); }
public MarkGeometryArc(Arc arc) : base() { Radius = arc.Radius; StartAngle = GeometricArithmeticModule.ToRadians(arc.StartAngle); EndAngle = GeometricArithmeticModule.ToRadians(arc.EndAngle); CentrePoint = new MarkGeometryPoint(arc.Center); Update(); }
public MarkGeometryPath(MarkGeometryCircle circle, double minimumFacetLength) : base() { int nSegments = (int)Math.Floor(GeometricArithmeticModule.CalculatePerimeter(circle) / minimumFacetLength); Points.AddRange(GeometricArithmeticModule.Explode(circle, nSegments + 1)); CentrePoint = circle.CentrePoint; Update(); }
private void FetchDXF(string filePathIn) { if (!File.Exists(filePathIn)) { _geometriesBuffer = null; } // attempt to load from cache if it exists else load using getter _geometriesBuffer = GeometricArithmeticModule.ExtractLabelledGeometriesFromDXF(filePathIn); }
public List <IMarkGeometry> FetchDXF(string filePathIn) { if (!File.Exists(filePathIn)) { return(null); } // attempt to load from cache if it exists else load using getter return(_dxfCachedLoader.TryGet(filePathIn, () => GeometricArithmeticModule.ExtractGeometriesFromDXF(filePathIn))); }
public MarkGeometryPath(MarkGeometryArc arc, double minimumFacetLength) : base() { int nSegments = (int)Math.Floor(GeometricArithmeticModule.CalculatePerimeter(arc) / minimumFacetLength); Points.AddRange((MarkGeometryPoint[])arc); CentrePoint = arc.CentrePoint; Fill = arc.Fill; Stroke = arc.Stroke; Update(); }
/// <summary> /// Create and arc from three points. /// </summary> /// <param name="centre">The centre of the arc.</param> /// <param name="p1">The starting point</param> /// <param name="p2">The end point</param> public MarkGeometryArc(MarkGeometryPoint centre, MarkGeometryPoint p1, MarkGeometryPoint p2) { Radius = GeometricArithmeticModule.ABSMeasure(centre, p1); StartAngle = GeometricArithmeticModule.CalculateAngle(centre, p1); EndAngle = GeometricArithmeticModule.CalculateAngle(centre, p2); CentrePoint = centre; StartPoint = p1; EndPoint = p2; Update(); }
public override void Transform(Matrix4x4 transformationMatrixIn) { for (int i = 0; i < Points.Count; i++) { Points[i].Transform(transformationMatrixIn); } Width = GeometricArithmeticModule.ABSMeasure2D(TopLeftPoint, TopRightPoint); Height = GeometricArithmeticModule.ABSMeasure2D(TopLeftPoint, BottomLeftPoint); Update(); }
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 )); }
private void Create(IList <MarkGeometryLine> lines) { var extents = GeometricArithmeticModule.CalculateExtents(lines); Create(extents.Centre.X, extents.Centre.Y, extents.Hypotenuse); foreach (var line in lines) { if (!Insert(line)) { throw new Exception($"Error while attempting to insert line: {line}"); } } }
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); }
public bool SaveAsDXF(string filename) { if (filename == null || filename.Length <= 0) { return(false); } string layerName; DxfDocument dxfDocument = new DxfDocument(new netDxf.Header.HeaderVariables()); layerName = "points"; foreach (MarkGeometryPoint point in Points) { dxfDocument.AddEntity(point.GetAsDXFEntity(layerName)); } layerName = "arcs"; foreach (MarkGeometryArc arc in Arcs) { dxfDocument.AddEntity(arc.GetAsDXFEntity(layerName)); } layerName = "arcs"; foreach (MarkGeometryCircle circle in Circles) { dxfDocument.AddEntity(circle.GetAsDXFEntity(layerName)); } layerName = "lines"; foreach (MarkGeometryLine line in Lines) { dxfDocument.AddEntity(line.GetAsDXFEntity(layerName)); } layerName = "paths"; foreach (MarkGeometryPath path in Paths) { foreach (MarkGeometryLine line in GeometricArithmeticModule.ToLines(path.Points)) { dxfDocument.AddEntity(line.GetAsDXFEntity(layerName)); } } // TODO : add support for other geometric objects and shapes e.g. splines, ellipses, etc // Also could optimise the object heirarchy (i.e. saving entities in an efficient order) dxfDocument.Save(filename); return(File.Exists(filename)); }
private IntersectionsBinaryTree Intersect(MarkGeometryLine line, LineEquation equation) { if (!equation.PassesThroughRect(Boundary)) { return(null); } // using binary tree to sort points relative to the line's starting point var intersections = new IntersectionsBinaryTree(line.StartPoint); if (ChildrenExists) { IntersectionsBinaryTree childIntersections; if ((childIntersections = NorthWest.Intersect(line)) != null) { intersections.InsertRange(childIntersections); } if ((childIntersections = NorthEast.Intersect(line)) != null) { intersections.InsertRange(childIntersections); } if ((childIntersections = SouthWest.Intersect(line)) != null) { intersections.InsertRange(childIntersections); } if ((childIntersections = SouthEast.Intersect(line)) != null) { intersections.InsertRange(childIntersections); } } MarkGeometryPoint intersection; for (int i = 0; i < Segments.Count; i++) { if (( intersection = GeometricArithmeticModule.CalculateIntersection2D( line, Segments[i] )) != null ) { intersections.Insert(intersection); } } return(intersections); }
public static Matrix4x4 GetRelativeTransform(MRecipe recipe, MRecipeDevice device) { if (device.Parent == null) { recipe.UpdateParents(); } return(GeometricArithmeticModule.CombineTransformations( // add device's transform device.TransformInfo.ToMatrix4x4(), // add plate's transform (device.Parent as MRecipeBaseNode).TransformInfo.ToMatrix4x4() )); }